stack_master 2.17.1 → 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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/stack_master +3 -5
  4. data/lib/stack_master/aws_driver/cloud_formation.rb +4 -4
  5. data/lib/stack_master/aws_driver/s3.rb +7 -7
  6. data/lib/stack_master/change_set.rb +7 -11
  7. data/lib/stack_master/cli.rb +32 -26
  8. data/lib/stack_master/command.rb +1 -5
  9. data/lib/stack_master/commands/apply.rb +34 -19
  10. data/lib/stack_master/commands/delete.rb +4 -4
  11. data/lib/stack_master/commands/drift.rb +5 -9
  12. data/lib/stack_master/commands/events.rb +4 -6
  13. data/lib/stack_master/commands/init.rb +14 -14
  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/outputs.rb +1 -1
  17. data/lib/stack_master/commands/status.rb +4 -4
  18. data/lib/stack_master/commands/terminal_helper.rb +3 -3
  19. data/lib/stack_master/commands/tidy.rb +14 -16
  20. data/lib/stack_master/config.rb +8 -11
  21. data/lib/stack_master/diff.rb +2 -2
  22. data/lib/stack_master/parameter_loader.rb +1 -2
  23. data/lib/stack_master/parameter_resolver.rb +14 -17
  24. data/lib/stack_master/parameter_resolvers/ami_finder.rb +1 -2
  25. data/lib/stack_master/parameter_resolvers/ejson.rb +4 -4
  26. data/lib/stack_master/parameter_resolvers/latest_ami_by_tags.rb +1 -1
  27. data/lib/stack_master/parameter_resolvers/latest_container.rb +3 -3
  28. data/lib/stack_master/parameter_resolvers/one_password.rb +5 -5
  29. data/lib/stack_master/parameter_resolvers/sso_group_id.rb +1 -1
  30. data/lib/stack_master/parameter_resolvers/stack_output.rb +7 -11
  31. data/lib/stack_master/parameter_validator.rb +1 -5
  32. data/lib/stack_master/prompter.rb +1 -1
  33. data/lib/stack_master/resolver_array.rb +2 -2
  34. data/lib/stack_master/role_assumer.rb +1 -1
  35. data/lib/stack_master/security_group_finder.rb +4 -4
  36. data/lib/stack_master/sns_topic_finder.rb +1 -1
  37. data/lib/stack_master/sparkle_formation/compile_time/allowed_pattern_validator.rb +1 -1
  38. data/lib/stack_master/sparkle_formation/compile_time/definitions_validator.rb +1 -1
  39. data/lib/stack_master/sparkle_formation/compile_time/value_builder.rb +7 -7
  40. data/lib/stack_master/sparkle_formation/compile_time/value_validator.rb +1 -3
  41. data/lib/stack_master/sparkle_formation/template_file.rb +2 -2
  42. data/lib/stack_master/sso_group_id_finder.rb +3 -3
  43. data/lib/stack_master/stack.rb +6 -4
  44. data/lib/stack_master/stack_definition.rb +3 -4
  45. data/lib/stack_master/stack_differ.rb +32 -9
  46. data/lib/stack_master/template_compilers/json.rb +1 -1
  47. data/lib/stack_master/template_compilers/sparkle_formation.rb +2 -2
  48. data/lib/stack_master/template_utils.rb +2 -2
  49. data/lib/stack_master/test_driver/cloud_formation.rb +11 -3
  50. data/lib/stack_master/test_driver/s3.rb +2 -3
  51. data/lib/stack_master/utils.rb +3 -6
  52. data/lib/stack_master/validator.rb +1 -1
  53. data/lib/stack_master/version.rb +1 -1
  54. data/lib/stack_master.rb +1 -1
  55. metadata +6 -5
@@ -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,23 +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(
23
- "Stack \"#{stack_definition.stack_name}\" in \"#{stack_definition.region}\" " \
24
- "missing template \"#{rel_path(template)}\""
25
- )
26
- end
27
- 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
+ )
28
28
  end
29
29
 
30
30
  templates.each do |path|
@@ -46,21 +46,19 @@ module StackMaster
46
46
  # template directories) this won't find the right directory.
47
47
  template_dir = @config.template_dir || File.join(@config.base_dir, 'templates')
48
48
 
49
- 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}')))
50
50
  dynamics_dir = File.join(template_dir, 'dynamics')
51
51
 
52
52
  # Exclude sparkleformation dynamics
53
53
  # TODO: Should this filter out anything with 'dynamics', not just the first
54
54
  # subdirectory?
55
- templates = templates.select do |path|
55
+ templates.select do |path|
56
56
  !path.start_with?(dynamics_dir)
57
57
  end
58
-
59
- templates
60
58
  end
61
59
 
62
60
  def find_parameter_files
63
- 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}')))
64
62
  end
65
63
  end
66
64
  end
@@ -26,13 +26,13 @@ module StackMaster
26
26
  )
27
27
 
28
28
  def self.search_up_and_chdir(config_file)
29
- return config_file unless File.dirname(config_file) == "."
29
+ return config_file unless File.dirname(config_file) == '.'
30
30
 
31
31
  dir = Dir.pwd
32
- parent_dir = File.expand_path("..", Dir.pwd)
32
+ parent_dir = File.expand_path('..', Dir.pwd)
33
33
  while parent_dir != dir && !File.exist?(File.join(dir, config_file))
34
34
  dir = parent_dir
35
- parent_dir = File.expand_path("..", dir)
35
+ parent_dir = File.expand_path('..', dir)
36
36
  end
37
37
 
38
38
  File.join(dir, config_file)
@@ -45,10 +45,9 @@ module StackMaster
45
45
  @parameters_dir = config.fetch('parameters_dir', nil)
46
46
  @stack_defaults = config.fetch('stack_defaults', {})
47
47
  @region_aliases = Utils.underscore_keys_to_hyphen(config.fetch('region_aliases', {}))
48
- @region_to_aliases = @region_aliases.inject({}) do |hash, (key, value)|
48
+ @region_to_aliases = @region_aliases.each_with_object({}) do |(key, value), hash|
49
49
  hash[value] ||= []
50
50
  hash[value] << key
51
- hash
52
51
  end
53
52
  @region_defaults = normalise_region_defaults(config.fetch('region_defaults', {}))
54
53
  @stacks = []
@@ -86,7 +85,7 @@ module StackMaster
86
85
  @template_compilers = default_template_compilers.merge(@template_compilers)
87
86
  end
88
87
 
89
- def populate_template_compilers user_defined_compilers
88
+ def populate_template_compilers(user_defined_compilers)
90
89
  user_defined_compilers.each do |key, val|
91
90
  @template_compilers[key.to_sym] = val.to_sym
92
91
  end
@@ -98,7 +97,7 @@ module StackMaster
98
97
  json: :json,
99
98
  yml: :yaml,
100
99
  yaml: :yaml,
101
- erb: :yaml_erb,
100
+ erb: :yaml_erb
102
101
  }
103
102
  end
104
103
 
@@ -108,9 +107,8 @@ module StackMaster
108
107
  end
109
108
 
110
109
  def resolve_region_aliases(stacks)
111
- stacks.inject({}) do |hash, (region, attributes)|
110
+ stacks.each_with_object({}) do |(region, attributes), hash|
112
111
  hash[unalias_region(region)] = attributes
113
- hash
114
112
  end
115
113
  end
116
114
 
@@ -141,10 +139,9 @@ module StackMaster
141
139
  end
142
140
 
143
141
  def normalise_region_defaults(region_defaults)
144
- region_defaults.inject({}) do |normalised_aliases, (region_or_alias, value)|
142
+ region_defaults.each_with_object({}) do |(region_or_alias, value), normalised_aliases|
145
143
  region = unalias_region(region_or_alias)
146
144
  normalised_aliases[Utils.underscore_to_hyphen(region)] = value
147
- normalised_aliases
148
145
  end
149
146
  end
150
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
@@ -7,13 +7,12 @@ module StackMaster
7
7
  def self.load(parameter_files: [], parameters: {})
8
8
  StackMaster.debug 'Searching for parameter files...'
9
9
  all_parameters = parameter_files.map { |file_name| load_parameters(file_name) } + [parameters]
10
- 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|
11
11
  template_parameters = create_template_parameters(parameters)
12
12
  compile_time_parameters = create_compile_time_parameters(parameters)
13
13
 
14
14
  merge_and_camelize(hash[:template_parameters], template_parameters)
15
15
  merge_and_camelize(hash[:compile_time_parameters], compile_time_parameters)
16
- hash
17
16
  end
18
17
  end
19
18
 
@@ -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,11 @@ 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)
52
51
 
53
52
  resolve_parameter_resolver_hash(key, parameter_value)
54
53
  rescue Aws::CloudFormation::Errors::ValidationError
@@ -73,15 +72,13 @@ module StackMaster
73
72
  end
74
73
  end
75
74
 
76
- def assume_role_if_present(account, role, key)
75
+ def assume_role_if_present(account, role, key, &block)
77
76
  return yield if account.nil? && role.nil?
78
77
  if account.nil? || role.nil?
79
78
  raise InvalidParameter, "Both 'account' and 'role' are required to assume role for parameter '#{key}'"
80
79
  end
81
80
 
82
- role_assumer.assume_role(account, role) do
83
- yield
84
- end
81
+ role_assumer.assume_role(account, role, &block)
85
82
  end
86
83
 
87
84
  def resolve_array_parameter_values(key, parameter_values)
@@ -114,9 +111,9 @@ module StackMaster
114
111
  end
115
112
 
116
113
  def validate_parameter_value!(key, parameter_value)
117
- if parameter_value.keys.size != 1
118
- raise InvalidParameter, "#{key} hash contained more than one key: #{parameter_value.inspect}"
119
- end
114
+ return if parameter_value.keys.size == 1
115
+
116
+ raise InvalidParameter, "#{key} hash contained more than one key: #{parameter_value.inspect}"
120
117
  end
121
118
 
122
119
  def role_assumer
@@ -6,12 +6,11 @@ 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)
@@ -22,10 +22,10 @@ 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 ' \
27
- "#{@stack_definition.stack_name} in #{@stack_definition.region}"
28
- 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}"
29
29
  end
30
30
 
31
31
  def decrypt_ejson_file
@@ -10,7 +10,7 @@ module StackMaster
10
10
  end
11
11
 
12
12
  def resolve(value)
13
- filters = @ami_finder.build_filters_from_string(value, prefix = "tag")
13
+ filters = @ami_finder.build_filters_from_string(value, prefix = 'tag')
14
14
  @ami_finder.find_latest_ami(filters)&.image_id
15
15
  end
16
16
  end
@@ -10,7 +10,7 @@ module StackMaster
10
10
 
11
11
  def resolve(parameters)
12
12
  if parameters['repository_name'].nil?
13
- raise ArgumentError, "repository_name parameter is required but was not supplied"
13
+ raise ArgumentError, 'repository_name parameter is required but was not supplied'
14
14
  end
15
15
 
16
16
  @region = parameters['region'] || @stack_definition.region
@@ -43,8 +43,8 @@ module StackMaster
43
43
  registry_id: registry_id,
44
44
  next_token: next_token,
45
45
  filter: {
46
- tag_status: "TAGGED",
47
- },
46
+ tag_status: 'TAGGED'
47
+ }
48
48
  }
49
49
  )
50
50
 
@@ -16,7 +16,7 @@ module StackMaster
16
16
  def resolve(params = {})
17
17
  if ENV.keys.grep(/OP_SESSION_\w+$/).empty?
18
18
  raise OnePasswordNotAbleToAuthenticate,
19
- "1password requires the `OP_SESSION_<name>` to be set, (remember to sign in?)"
19
+ '1password requires the `OP_SESSION_<name>` to be set, (remember to sign in?)'
20
20
  end
21
21
 
22
22
  get_items(params)
@@ -25,7 +25,7 @@ module StackMaster
25
25
  private
26
26
 
27
27
  def validate_op_installed?
28
- %x(op --version)
28
+ `op --version`
29
29
  rescue Errno::ENOENT => exception
30
30
  raise OnePasswordBinaryNotFound, "The op cli needs to be installed and in the PATH, #{exception}"
31
31
  end
@@ -53,7 +53,7 @@ module StackMaster
53
53
 
54
54
  def op_get_item(item, vault)
55
55
  validate_op_installed?
56
- item = %x(op get item --vault='#{vault}' '#{item}' 2>&1)
56
+ item = `op get item --vault='#{vault}' '#{item}' 2>&1`
57
57
  item if validate_response?(item)
58
58
  end
59
59
 
@@ -79,9 +79,9 @@ module StackMaster
79
79
  def get_items(params)
80
80
  case params['type']
81
81
  when 'password'
82
- return get_password(params['title'], params['vault'])
82
+ get_password(params['title'], params['vault'])
83
83
  when 'secureNote'
84
- return get_secure_note(params['title'], params['vault'])
84
+ get_secure_note(params['title'], params['vault'])
85
85
  end
86
86
  end
87
87
  end
@@ -15,7 +15,7 @@ module StackMaster
15
15
  private
16
16
 
17
17
  def sso_group_id_finder
18
- StackMaster::SsoGroupIdFinder.new()
18
+ StackMaster::SsoGroupIdFinder.new
19
19
  end
20
20
  end
21
21
  end
@@ -17,18 +17,14 @@ module StackMaster
17
17
  def resolve(value)
18
18
  region, stack_name, output_name = parse!(value)
19
19
  stack = find_stack(stack_name, region)
20
- if stack
21
- output = stack.outputs.find do |stack_output|
22
- stack_output.output_key == output_name.camelize || stack_output.output_key == output_name
23
- end
24
- if output
25
- output.output_value
26
- else
27
- raise StackOutputNotFound, "Stack exists (#{stack_name}), but output does not: #{output_name}"
28
- end
29
- else
30
- raise StackNotFound, "Stack in StackOutput not found: #{value}"
20
+ raise StackNotFound, "Stack in StackOutput not found: #{value}" unless stack
21
+
22
+ output = stack.outputs.find do |stack_output|
23
+ stack_output.output_key == output_name.camelize || stack_output.output_key == output_name
31
24
  end
25
+ raise StackOutputNotFound, "Stack exists (#{stack_name}), but output does not: #{output_name}" unless output
26
+
27
+ output.output_value
32
28
  end
33
29
 
34
30
  private
@@ -14,11 +14,7 @@ module StackMaster
14
14
  missing_parameters.each do |parameter_name|
15
15
  message << " - #{parameter_name}\n"
16
16
  end
17
- if @stack_definition.parameter_files.empty?
18
- message << message_for_parameter_globs
19
- else
20
- message << message_for_parameter_files
21
- end
17
+ message << (@stack_definition.parameter_files.empty? ? message_for_parameter_globs : message_for_parameter_files)
22
18
  message
23
19
  end
24
20
 
@@ -10,7 +10,7 @@ module StackMaster
10
10
  StackMaster.stdin.getch.chomp
11
11
  else
12
12
  StackMaster.stdout.puts
13
- StackMaster.stdout.puts "STDOUT or STDIN was not a TTY. Defaulting to no. To force yes use -y"
13
+ StackMaster.stdout.puts 'STDOUT or STDIN was not a TTY. Defaulting to no. To force yes use -y'
14
14
  'n'
15
15
  end
16
16
  else
@@ -13,13 +13,13 @@ module StackMaster
13
13
  end
14
14
 
15
15
  def resolver_class
16
- fail "Method resolver_class not implemented on #{self.class}"
16
+ raise "Method resolver_class not implemented on #{self.class}"
17
17
  end
18
18
  end
19
19
 
20
20
  class Resolver
21
21
  def self.array_resolver(options = {})
22
- resolver_class ||= Object.const_get(self.name)
22
+ resolver_class ||= Object.const_get(name)
23
23
  array_resolver_class_name = options[:class_name] || resolver_class.to_s.demodulize.pluralize
24
24
 
25
25
  klass = Class.new(ResolverArray) do
@@ -48,7 +48,7 @@ module StackMaster
48
48
  {
49
49
  region: StackMaster.cloud_formation_driver.region,
50
50
  role_arn: "arn:aws:iam::#{account}:role/#{role}",
51
- role_session_name: "stack-master-role-assumer"
51
+ role_session_name: 'stack-master-role-assumer'
52
52
  }
53
53
  )
54
54
  end
@@ -15,10 +15,10 @@ module StackMaster
15
15
  groups = @resource.security_groups({
16
16
  filters: [
17
17
  {
18
- name: "group-name",
19
- values: [reference],
20
- },
21
- ],
18
+ name: 'group-name',
19
+ values: [reference]
20
+ }
21
+ ]
22
22
  })
23
23
 
24
24
  raise SecurityGroupNotFound, "No security group with name #{reference} found" unless groups.any?
@@ -21,7 +21,7 @@ module StackMaster
21
21
  private
22
22
 
23
23
  def topic_name_from_arn(arn)
24
- arn.split(":")[5]
24
+ arn.split(':')[5]
25
25
  end
26
26
  end
27
27
  end
@@ -22,7 +22,7 @@ module StackMaster
22
22
 
23
23
  def invalid_values
24
24
  values = build_values(@definition, @parameter)
25
- values.reject { |value| value.to_s.match(%r{#{@definition[KEY]}}) }
25
+ values.reject { |value| value.to_s.match(/#{@definition[KEY]}/) }
26
26
  end
27
27
 
28
28
  def create_error
@@ -4,7 +4,7 @@ module StackMaster
4
4
  module SparkleFormation
5
5
  module CompileTime
6
6
  class DefinitionsValidator
7
- VALID_TYPES = [:string, :number]
7
+ VALID_TYPES = %i[string number]
8
8
  def initialize(definitions)
9
9
  @definitions = definitions
10
10
  end
@@ -21,16 +21,16 @@ module StackMaster
21
21
  end
22
22
 
23
23
  def convert_strings_to_array
24
- if @definition[:multiple] && @value.is_a?(String)
25
- @value = @value.split(',').map(&:strip)
26
- end
24
+ return unless @definition[:multiple] && @value.is_a?(String)
25
+
26
+ @value = @value.split(',').map(&:strip)
27
27
  end
28
28
 
29
29
  def convert_strings_to_numbers
30
- if @definition[:type] == :number
31
- @value = @value.to_f if @value.is_a?(String)
32
- @value = @value.map { |item| item.is_a?(String) ? item.to_f : item } if @value.is_a?(Array)
33
- end
30
+ return if @definition[:type] != :number
31
+
32
+ @value = @value.to_f if @value.is_a?(String)
33
+ @value = @value.map { |item| item.is_a?(String) ? item.to_f : item } if @value.is_a?(Array)
34
34
  end
35
35
  end
36
36
  end
@@ -27,9 +27,7 @@ module StackMaster
27
27
  private
28
28
 
29
29
  def convert_to_array(definition, parameter)
30
- if definition[:multiple] && parameter.is_a?(String)
31
- return parameter.split(',').map(&:strip)
32
- end
30
+ return parameter.split(',').map(&:strip) if definition[:multiple] && parameter.is_a?(String)
33
31
 
34
32
  parameter.is_a?(Array) ? parameter : [parameter]
35
33
  end
@@ -49,14 +49,14 @@ module StackMaster
49
49
  def _joined_file(file_name, vars = {})
50
50
  join!(Template.render('joined_file', file_name, vars))
51
51
  end
52
- alias_method :joined_file!, :_joined_file
52
+ alias joined_file! _joined_file
53
53
  end
54
54
 
55
55
  module UserDataFile
56
56
  def _user_data_file(file_name, vars = {})
57
57
  base64!(join!(Template.render('user_data', file_name, vars)))
58
58
  end
59
- alias_method :user_data_file!, :_user_data_file
59
+ alias user_data_file! _user_data_file
60
60
  end
61
61
  end
62
62
  end
@@ -19,9 +19,9 @@ module StackMaster
19
19
  alternate_identifier: {
20
20
  unique_attribute: {
21
21
  attribute_path: 'displayName',
22
- attribute_value: match[:group_name],
23
- },
24
- },
22
+ attribute_value: match[:group_name]
23
+ }
24
+ }
25
25
  }
26
26
  )
27
27
  return response.group_id
@@ -20,9 +20,8 @@ module StackMaster
20
20
  TemplateUtils
21
21
  .template_hash(template)
22
22
  .fetch('Parameters', {})
23
- .inject({}) do |result, (parameter_name, description)|
23
+ .each_with_object({}) do |(parameter_name, description), result|
24
24
  result[parameter_name] = description['Default']&.to_s
25
- result
26
25
  end
27
26
  end
28
27
 
@@ -35,19 +34,22 @@ module StackMaster
35
34
  cf_stack = cf.describe_stacks({ stack_name: stack_name }).stacks.first
36
35
  return unless cf_stack
37
36
 
38
- parameters = cf_stack.parameters.inject({}) do |params_hash, param_struct|
37
+ parameters = cf_stack.parameters.each_with_object({}) do |param_struct, params_hash|
39
38
  params_hash[param_struct.parameter_key] = param_struct.parameter_value
40
- params_hash
41
39
  end
42
40
  template_body ||= cf.get_template({ stack_name: stack_name, template_stage: 'Original' }).template_body
43
41
  template_format = TemplateUtils.identify_template_format(template_body)
44
42
  stack_policy_body ||= cf.get_stack_policy({ stack_name: stack_name }).stack_policy_body
45
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 || {}
46
47
 
47
48
  new(region: region,
48
49
  stack_name: stack_name,
49
50
  stack_id: cf_stack.stack_id,
50
51
  parameters: parameters,
52
+ tags: tags,
51
53
  template_body: template_body,
52
54
  template_format: template_format,
53
55
  outputs: outputs,
@@ -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 &&
@@ -74,13 +74,12 @@ module StackMaster
74
74
  end
75
75
 
76
76
  def s3_files
77
- files.inject({}) do |hash, file|
77
+ files.each_with_object({}) do |file, hash|
78
78
  path = File.join(files_dir, file)
79
79
  hash[file] = {
80
80
  path: path,
81
81
  body: File.read(path)
82
82
  }
83
- hash
84
83
  end
85
84
  end
86
85