knife-cloudformation 0.2.24 → 0.5.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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/README.md +16 -0
  4. data/knife-cloudformation.gemspec +14 -4
  5. data/lib/knife-cloudformation.rb +0 -28
  6. data/lib/knife-cloudformation/version.rb +1 -1
  7. metadata +18 -80
  8. data/lib/chef/knife/cloudformation_create.rb +0 -147
  9. data/lib/chef/knife/cloudformation_describe.rb +0 -99
  10. data/lib/chef/knife/cloudformation_destroy.rb +0 -84
  11. data/lib/chef/knife/cloudformation_events.rb +0 -117
  12. data/lib/chef/knife/cloudformation_export.rb +0 -162
  13. data/lib/chef/knife/cloudformation_import.rb +0 -141
  14. data/lib/chef/knife/cloudformation_inspect.rb +0 -206
  15. data/lib/chef/knife/cloudformation_list.rb +0 -72
  16. data/lib/chef/knife/cloudformation_promote.rb +0 -40
  17. data/lib/chef/knife/cloudformation_update.rb +0 -137
  18. data/lib/chef/knife/cloudformation_validate.rb +0 -36
  19. data/lib/knife-cloudformation/cache.rb +0 -385
  20. data/lib/knife-cloudformation/knife.rb +0 -9
  21. data/lib/knife-cloudformation/knife/base.rb +0 -195
  22. data/lib/knife-cloudformation/knife/stack.rb +0 -197
  23. data/lib/knife-cloudformation/knife/template.rb +0 -213
  24. data/lib/knife-cloudformation/monkey_patch.rb +0 -8
  25. data/lib/knife-cloudformation/monkey_patch/stack.rb +0 -195
  26. data/lib/knife-cloudformation/provider.rb +0 -225
  27. data/lib/knife-cloudformation/utils.rb +0 -24
  28. data/lib/knife-cloudformation/utils/animal_strings.rb +0 -28
  29. data/lib/knife-cloudformation/utils/debug.rb +0 -31
  30. data/lib/knife-cloudformation/utils/json.rb +0 -64
  31. data/lib/knife-cloudformation/utils/object_storage.rb +0 -28
  32. data/lib/knife-cloudformation/utils/output.rb +0 -79
  33. data/lib/knife-cloudformation/utils/path_selector.rb +0 -99
  34. data/lib/knife-cloudformation/utils/ssher.rb +0 -29
  35. data/lib/knife-cloudformation/utils/stack_exporter.rb +0 -271
  36. data/lib/knife-cloudformation/utils/stack_parameter_scrubber.rb +0 -37
  37. data/lib/knife-cloudformation/utils/stack_parameter_validator.rb +0 -124
@@ -1,197 +0,0 @@
1
- require 'knife-cloudformation'
2
- require 'sparkle_formation'
3
-
4
- module KnifeCloudformation
5
- module Knife
6
- # Stack handling helper methods
7
- module Stack
8
-
9
- module InstanceMethods
10
-
11
- # un-packed stack name joiner/identifier
12
- UNPACK_NAME_JOINER = '-sfn-'
13
- # maximum number of attempts to get valid parameter value
14
- MAX_PARAMETER_ATTEMPTS = 5
15
-
16
- # Apply any defined remote stacks
17
- #
18
- # @param stack [Miasma::Models::Orchestration::Stack]
19
- # @return [Miasma::Models::Orchestration::Stack]
20
- def apply_stacks!(stack)
21
- action = self.class.name.downcase.end_with?('create') ? :create : :update
22
- remote_stacks = Chef::Config[:knife][:cloudformation].
23
- fetch(action, {}).fetch(:apply_stacks, [])
24
- remote_stacks.each do |stack_name|
25
- remote_stack = provider.connection.stacks.get(stack_name)
26
- apply_nested_stacks!(remote_stack, stack)
27
- if(remote_stack)
28
- stack.apply_stack(remote_stack)
29
- else
30
- apply_unpacked_stack!(stack_name, stack)
31
- end
32
- end
33
- stack
34
- end
35
-
36
- # Detect nested stacks and apply
37
- #
38
- # @param remote_stack [Miasma::Models::Orchestration::Stack] nested stack
39
- # @param stack [Miasma::Models::Orchestration::Stack] current stack
40
- # @return [Miasma::Models::Orchestration::Stack]
41
- # @todo ported from a proto branch and needs to be refactored.
42
- # this implementation is some what shady
43
- def apply_nested_stacks!(remote_stack, stack)
44
- remote_stack.resources.all.each do |resource|
45
- if(resource.type == 'AWS::CloudFormation::Stack')
46
- nested_stack = provider.connection.stacks.get(resource.id)
47
- apply_nested_stacks!(nested_stack, stack)
48
- stack.apply_stack(nested_stack)
49
- end
50
- end
51
- stack
52
- end
53
-
54
- # Apply all stacks from an unpacked stack
55
- #
56
- # @param stack_name [String] name of parent stack
57
- # @param stack [Miasma::Models::Orchestration::Stack]
58
- # @return [Miasma::Models::Orchestration::Stack]
59
- def apply_unpacked_stack!(stack_name, stack)
60
- result = provider.connection.stacks.all.find_all do |remote_stack|
61
- remote_stack.name.start_with?("#{stack_name}#{UNPACK_NAME_JOINER}")
62
- end.sort_by(&:name).map do |remote_stack|
63
- stack.apply_stack(remote_stack)
64
- end
65
- unless(result.empty?)
66
- stack
67
- else
68
- ui.error "Failed to apply requested stack. Unable to locate. (#{stack_name})"
69
- exit 1
70
- end
71
- end
72
-
73
- # Unpack nested stack and run action on each stack, applying
74
- # the previous stacks automatically
75
- #
76
- # @param name [String] container stack name
77
- # @param file [Hash] stack template
78
- # @param action [String] create or update
79
- # @return [TrueClass]
80
- def unpack_nesting(name, file, action)
81
-
82
- # @todo move this init into setup
83
- Chef::Config[:knife][:cloudformation][action.to_sym] ||= Mash.new
84
- Chef::Config[:knife][:cloudformation][action.to_sym][:apply_stacks] ||= []
85
-
86
- orig_options = Chef::Config[:knife][:cloudformation][:options].dup
87
- stack_count = 0
88
-
89
- file['Resources'].each do |stack_resource_name, stack_resource|
90
-
91
- nested_stack_name = "#{name}#{UNPACK_NAME_JOINER}#{Kernel.sprintf('%0.3d', stack_count)}-#{stack_resource_name}"
92
- nested_stack_template = stack_resource['Properties']['Stack']
93
- Chef::Config[:knife][:cloudformation][:options] = orig_options.dup
94
-
95
- klass = Chef::Knife.const_get("Cloudformation#{action.to_s.capitalize}")
96
- nested_stack_runner = klass.new
97
- nested_stack_runner.config = config.dup
98
- nested_stack_runner.name_args.push(nested_stack_name)
99
- Chef::Config[:knife][:cloudformation][:template] = nested_stack_template
100
- nested_stack_runner.run
101
- unless(config[:print_only])
102
- Chef::Config[:knife][:cloudformation][action.to_sym][:apply_stacks].push(nested_stack_name).uniq!
103
- end
104
- Chef::Config[:knife][:cloudformation][:template] = nil
105
- provider.connection.stacks.reload
106
- stack_count += 1
107
-
108
- end
109
-
110
- true
111
- end
112
-
113
- # Prompt for parameter values and store result
114
- #
115
- # @param stack [Hash] stack template
116
- # @return [Hash]
117
- def populate_parameters!(stack, current_params={})
118
- if(Chef::Config[:knife][:cloudformation][:interactive_parameters])
119
- if(stack['Parameters'])
120
- Chef::Config[:knife][:cloudformation][:options][:parameters] ||= Mash.new
121
- stack.fetch('Parameters', {}).each do |k,v|
122
- next if Chef::Config[:knife][:cloudformation][:options][:parameters][k]
123
- attempt = 0
124
- valid = false
125
- until(valid)
126
- attempt += 1
127
- default = Chef::Config[:knife][:cloudformation][:options][:parameters].fetch(
128
- k, current_params.fetch(
129
- k, v['Default']
130
- )
131
- )
132
- answer = ui.ask_question("#{k.split(/([A-Z]+[^A-Z]*)/).find_all{|s|!s.empty?}.join(' ')}: ", :default => default)
133
- validation = KnifeCloudformation::Utils::StackParameterValidator.validate(answer, v)
134
- if(validation == true)
135
- Chef::Config[:knife][:cloudformation][:options][:parameters][k] = answer
136
- valid = true
137
- else
138
- validation.each do |validation_error|
139
- ui.error validation_error.last
140
- end
141
- end
142
- if(attempt > MAX_PARAMETER_ATTEMPTS)
143
- ui.fatal 'Failed to receive allowed parameter!'
144
- exit 1
145
- end
146
- end
147
- end
148
- end
149
- end
150
- stack
151
- end
152
-
153
- end
154
-
155
- module ClassMethods
156
- end
157
-
158
- # Load methods into class and define options
159
- #
160
- # @param klass [Class]
161
- def self.included(klass)
162
- klass.class_eval do
163
- extend KnifeCloudformation::Knife::Stack::ClassMethods
164
- include KnifeCloudformation::Knife::Stack::InstanceMethods
165
-
166
- option(:parameter,
167
- :short => '-p KEY:VALUE',
168
- :long => '--parameter KEY:VALUE',
169
- :description => 'Set parameter. Can be used multiple times.',
170
- :proc => lambda {|val|
171
- parts = val.split(':')
172
- key = parts.first
173
- value = parts[1, parts.size].join(':')
174
- Chef::Config[:knife][:cloudformation][:options][:parameters] ||= Mash.new
175
- Chef::Config[:knife][:cloudformation][:options][:parameters][key] = value
176
- }
177
- )
178
- option(:polling,
179
- :long => '--[no-]poll',
180
- :description => 'Enable stack event polling.',
181
- :boolean => true,
182
- :default => true,
183
- :proc => lambda {|val| Chef::Config[:knife][:cloudformation][:poll] = val }
184
- )
185
- option(:interactive_parameters,
186
- :long => '--[no-]parameter-prompts',
187
- :boolean => true,
188
- :default => true,
189
- :description => 'Do not prompt for input on dynamic parameters',
190
- :proc => lambda{|val| Chef::Config[:knife][:cloudformation][:interactive_parameters] = val }
191
- )
192
- end
193
- end
194
-
195
- end
196
- end
197
- end
@@ -1,213 +0,0 @@
1
- require 'knife-cloudformation'
2
- require 'sparkle_formation'
3
-
4
- module KnifeCloudformation
5
- module Knife
6
- # Template handling helper methods
7
- module Template
8
-
9
- # cloudformation directories that should be ignored
10
- TEMPLATE_IGNORE_DIRECTORIES = %w(components dynamics registry)
11
-
12
- module InstanceMethods
13
-
14
- # Load the template file
15
- #
16
- # @param args [Symbol] options (:allow_missing)
17
- # @return [Hash] loaded template
18
- def load_template_file(*args)
19
- unless(Chef::Config[:knife][:cloudformation][:template])
20
- set_paths_and_discover_file!
21
- unless(File.exists?(Chef::Config[:knife][:cloudformation][:file].to_s))
22
- unless(args.include?(:allow_missing))
23
- ui.fatal "Invalid formation file path provided: #{Chef::Config[:knife][:cloudformation][:file]}"
24
- exit 1
25
- end
26
- end
27
- end
28
- if(Chef::Config[:knife][:cloudformation][:template])
29
- Chef::Config[:knife][:cloudformation][:template]
30
- elsif(Chef::Config[:knife][:cloudformation][:file])
31
- if(Chef::Config[:knife][:cloudformation][:processing])
32
- sf = SparkleFormation.compile(Chef::Config[:knife][:cloudformation][:file], :sparkle)
33
- if(sf.nested? && !sf.isolated_nests?)
34
- raise TypeError.new('Template does not contain isolated stack nesting! Cannot process in existing state.')
35
- end
36
- if(sf.nested? && Chef::Config[:knife][:cloudformation][:apply_nesting])
37
- sf.apply_nesting do |stack_name, stack_definition|
38
- bucket = provider.connection.api_for(:storage).buckets.get(
39
- Chef::Config[:knife][:cloudformation][:nesting_bucket]
40
- )
41
- if(config[:print_only])
42
- "http://example.com/bucket/#{name_args.first}_#{stack_name}.json"
43
- else
44
- unless(bucket)
45
- raise "Failed to locate configured bucket for stack template storage (#{bucket})!"
46
- end
47
- file = bucket.files.build
48
- file.name = "#{name_args.first}_#{stack_name}.json"
49
- file.content_type = 'text/json'
50
- file.body = MultiJson.dump(KnifeCloudformation::Utils::StackParameterScrubber.scrub!(stack_definition))
51
- file.save
52
- # TODO: what if we need extra params?
53
- url = URI.parse(file.url)
54
- "#{url.scheme}://#{url.host}#{url.path}"
55
- end
56
- end
57
- else
58
- sf.dump.merge('sfn_nested_stack' => !!sf.nested?)
59
- end
60
- else
61
- _from_json(File.read(Chef::Config[:knife][:cloudformation][:file]))
62
- end
63
- end
64
- end
65
-
66
- # Apply template translation
67
- #
68
- # @param template [Hash]
69
- # @return [Hash]
70
- def translate_template(template)
71
- if(klass_name = Chef::Config[:knife][:cloudformation][:translate])
72
- klass = SparkleFormation::Translation.const_get(camel(klass_name))
73
- args = {
74
- :parameters => Chef::Config[:knife][:cloudformation][:options][:parameters]
75
- }
76
- if(chunk_size = Chef::Config[:knife][:cloudformation][:translate_chunk_size])
77
- args.merge!(
78
- :options => {
79
- :serialization_chunk_size => chunk_size
80
- }
81
- )
82
- end
83
- translator = klass.new(template, args)
84
- translator.translate!
85
- template = translator.translated
86
- ui.info "#{ui.color('Translation applied:', :bold)} #{ui.color(klass_name, :yellow)}"
87
- end
88
- template
89
- end
90
-
91
- # Set SparkleFormation paths and locate tempate
92
- #
93
- # @return [TrueClass]
94
- def set_paths_and_discover_file!
95
- if(Chef::Config[:knife][:cloudformation][:base_directory])
96
- SparkleFormation.components_path = File.join(
97
- Chef::Config[:knife][:cloudformation][:base_directory], 'components'
98
- )
99
- SparkleFormation.dynamics_path = File.join(
100
- Chef::Config[:knife][:cloudformation][:base_directory], 'dynamics'
101
- )
102
- end
103
- if(!Chef::Config[:knife][:cloudformation][:file] && Chef::Config[:knife][:cloudformation][:file_path_prompt])
104
- root = File.expand_path(
105
- Chef::Config[:knife][:cloudformation].fetch(:base_directory,
106
- File.join(Dir.pwd, 'cloudformation')
107
- )
108
- ).split('/')
109
- bucket = root.pop
110
- root = root.join('/')
111
- directory = File.join(root, bucket)
112
- Chef::Config[:knife][:cloudformation][:file] = prompt_for_file(directory,
113
- :directories_name => 'Collections',
114
- :files_name => 'Templates',
115
- :ignore_directories => TEMPLATE_IGNORE_DIRECTORIES
116
- )
117
- else
118
- unless(Pathname(Chef::Config[:knife][:cloudformation][:file].to_s).absolute?)
119
- base_dir = Chef::Config[:knife][:cloudformation][:base_directory].to_s
120
- file = Chef::Config[:knife][:cloudformation][:file].to_s
121
- pwd = Dir.pwd
122
- Chef::Config[:knife][:cloudformation][:file] = [
123
- File.join(base_dir, file),
124
- File.join(pwd, file),
125
- File.join(pwd, 'cloudformation', file)
126
- ].detect do |file_path|
127
- File.file?(file_path)
128
- end
129
- end
130
- end
131
- true
132
- end
133
-
134
- end
135
-
136
- module ClassMethods
137
- end
138
-
139
- # Load methods into class and define options
140
- #
141
- # @param klass [Class]
142
- def self.included(klass)
143
- klass.class_eval do
144
- extend KnifeCloudformation::Knife::Template::ClassMethods
145
- include KnifeCloudformation::Knife::Template::InstanceMethods
146
- include KnifeCloudformation::Utils::PathSelector
147
-
148
- option(:processing,
149
- :long => '--[no-]processing',
150
- :description => 'Call the unicorns and explode the glitter bombs',
151
- :boolean => true,
152
- :default => false,
153
- :proc => lambda {|val| Chef::Config[:knife][:cloudformation][:processing] = val }
154
- )
155
- option(:file,
156
- :short => '-f PATH',
157
- :long => '--file PATH',
158
- :description => 'Path to Cloud Formation to process',
159
- :proc => lambda {|val|
160
- Chef::Config[:knife][:cloudformation][:file] = val
161
- }
162
- )
163
- option(:file_path_prompt,
164
- :long => '--[no-]file-path-prompt',
165
- :description => 'Interactive prompt for template path discovery',
166
- :boolean => true,
167
- :default => true,
168
- :proc => lambda {|val|
169
- Chef::Config[:knife][:cloudformation][:file_path_prompt] = val
170
- }
171
- )
172
- option(:base_directory,
173
- :long => '--cloudformation-directory PATH',
174
- :description => 'Path to cloudformation directory',
175
- :proc => lambda {|val| Chef::Config[:knife][:cloudformation][:base_directory] = val}
176
- )
177
- option(:no_base_directory,
178
- :long => '--no-cloudformation-directory',
179
- :description => 'Unset any value used for cloudformation path',
180
- :proc => lambda {|*val| Chef::Config[:knife][:cloudformation][:base_directory] = nil}
181
- )
182
- option(:translate,
183
- :long => '--translate PROVIDER',
184
- :description => 'Translate generated template to given provider',
185
- :proc => lambda {|val| Chef::Config[:knife][:cloudformation][:translate] = val}
186
- )
187
- option(:translate_chunk,
188
- :long => '--translate-chunk-size SIZE',
189
- :description => 'Chunk length for serialization',
190
- :proc => lambda {|val| Chef::Config[:knife][:cloudformation][:translate_chunk_size] = val}
191
- )
192
- option(:apply_nesting,
193
- :long => '--[no-]apply-nesting',
194
- :description => 'Apply stack nesting',
195
- :default => false,
196
- :boolean => true,
197
- :proc => lambda{|val| Chef::Config[:knife][:cloudformation][:apply_nesting] = val}
198
- )
199
- option(:nesting_bucket,
200
- :long => '--nesting-bucket',
201
- :description => 'Bucket to use for storing nested stack templates',
202
- :proc => lambda{|val| Chef::Config[:knife][:cloudformation][:nesting_bucket] = val}
203
- )
204
-
205
- Chef::Config[:knife][:cloudformation][:file_path_prompt] = true
206
-
207
- end
208
-
209
- end
210
-
211
- end
212
- end
213
- end
@@ -1,8 +0,0 @@
1
- require 'knife-cloudformation'
2
-
3
- module KnifeCloudformation
4
- # Container for monkey patches
5
- module MonkeyPatch
6
- autoload :Stack, 'knife-cloudformation/monkey_patch/stack'
7
- end
8
- end
@@ -1,195 +0,0 @@
1
- require 'base64'
2
- require 'knife-cloudformation'
3
-
4
- module KnifeCloudformation
5
- module MonkeyPatch
6
-
7
- # Expand stack model functionality
8
- module Stack
9
-
10
- include KnifeCloudformation::Utils::AnimalStrings
11
-
12
- ## Status helpers
13
-
14
- # Check for state suffix
15
- #
16
- # @param args [String, Symbol] state suffix to check for (multiple allowed)
17
- # @return [TrueClass, FalseClass] true if any matches found in argument list
18
- def status_ends_with?(*args)
19
- stat = status.to_s.downcase
20
- !!args.map(&:to_s).map(&:downcase).detect do |suffix|
21
- stat.end_with?(suffix)
22
- end
23
- end
24
-
25
- # Check for state prefix
26
- #
27
- # @param args [String, Symbol] state prefix to check for (multiple allowed)
28
- # @return [TrueClass, FalseClass] true if any matches found in argument list
29
- def status_starts_with?(*args)
30
- stat = status.to_s.downcase
31
- !!args.map(&:to_s).map(&:downcase).detect do |prefix|
32
- stat.start_with?(prefix)
33
- end
34
- end
35
-
36
- # Check for state inclusion
37
- #
38
- # @param args [String, Symbol] state string to check for (multiple allowed)
39
- # @return [TrueClass, FalseClass] true if any matches found in argument list
40
- def status_includes?(*args)
41
- stat = status.to_s.downcase
42
- !!args.map(&:to_s).map(&:downcase).detect do |string|
43
- stat.include?(string)
44
- end
45
- end
46
-
47
- # @return [TrueClass, FalseClass] stack is in progress
48
- def in_progress?
49
- status_ends_with?(:in_progress)
50
- end
51
-
52
- # @return [TrueClass, FalseClass] stack is in complete state
53
- def complete?
54
- status_ends_with?(:complete, :failed)
55
- end
56
-
57
- # @return [TrueClass, FalseClass] stack is failed state
58
- def failed?
59
- status_ends_with?(:failed) ||
60
- (status_includes?(:rollback) && status_ends_with?(:complete))
61
- end
62
-
63
- # @return [TrueClass, FalseClass] stack is in success state
64
- def success?
65
- !failed? && complete?
66
- end
67
-
68
- # @return [TrueClass, FalseClass] stack is creating
69
- def creating?
70
- in_progress? && status_starts_with?(:create)
71
- end
72
-
73
- # @return [TrueClass, FalseClass] stack is deleting
74
- def deleting?
75
- in_progress? && status_starts_with?(:delete)
76
- end
77
-
78
- # @return [TrueClass, FalseClass] stack is updating
79
- def updating?
80
- in_progress? && status_starts_with?(:update)
81
- end
82
-
83
- # @return [TrueClass, FalseClass] stack is rolling back
84
- def rollbacking?
85
- in_progress? && status_starts_with?(:rollback)
86
- end
87
-
88
- # @return [String] action currently being performed
89
- def performing
90
- if(in_progress?)
91
- status.to_s.downcase.split('_').first.to_sym
92
- end
93
- end
94
-
95
- ### Color coders
96
-
97
- # @return [TrueClass, FalseClass] stack is in red state
98
- def red?
99
- failed? || deleting?
100
- end
101
-
102
- # @return [TrueClass, FalseClass] stack is in green state
103
- def green?
104
- success?
105
- end
106
-
107
- # @return [TrueClass, FalseClass] stack is in yellow state
108
- def yellow?
109
- !red? && !green?
110
- end
111
-
112
- # Provides color of stack state. Red is an error state, yellow
113
- # is a warning state and green is a success state
114
- #
115
- # @return [Symbol] color of state (:red, :yellow, :green)
116
- def color_state
117
- red? ? :red : green? ? :green : :yellow
118
- end
119
-
120
- # Provides text of stack state. Danger is an error state, warning
121
- # is a warning state and success is a success state
122
- #
123
- # @return [Symbol] color of state (:danger, :warning, :success)
124
- def text_state
125
- red? ? :danger : green? ? :success : :warning
126
- end
127
-
128
- # @return [String] URL safe encoded stack id
129
- def encoded_id
130
- Base64.urlsafe_encode64(id)
131
- end
132
-
133
- # Whole number representation of current completion
134
- #
135
- # @param min [Integer] lowest allowed return value (defaults 5)
136
- # @return [Integer] percent complete (0..100)
137
- def percent_complete(min = 5)
138
- if(in_progress?)
139
- total_resources = load_template.fetch('Resources', []).size
140
- total_complete = resources.all.find_all do |resource|
141
- resource.resource_status.downcase.end_with?('complete')
142
- end.size
143
- result = ((total_complete.to_f / total_resources) * 100).to_i
144
- result > min.to_i ? result : min
145
- else
146
- 100
147
- end
148
- end
149
-
150
- # Apply stack outputs to current stack parameters
151
- #
152
- # @param remote_stack [Miasma::Orchestration::Stack]
153
- # @return [self]
154
- # @note setting `DisableApply` within parameter hash will
155
- # prevent parameters being overridden
156
- def apply_stack(remote_stack)
157
- default_key = 'Default'
158
- stack_parameters = template['Parameters']
159
- valid_parameters = Hash[
160
- stack_parameters.map do |key, val|
161
- unless(val['DisableApply'])
162
- [snake(key), key]
163
- end
164
- end.compact
165
- ]
166
- if(defined?(Chef::Config) && Chef::Config[:knife][:cloudformation][:ignore_parameters])
167
- valid_parameters = Hash[
168
- valid_parameters.map do |snake_param, camel_param|
169
- unless(Chef::Config[:knife][:cloudformation][:ignore_parameters].include?(camel_param))
170
- [snake_param, camel_param]
171
- end
172
- end.compact
173
- ]
174
- end
175
- if(persisted?)
176
- remote_stack.outputs.each do |output|
177
- if(param_key = valid_parameters[snake(output.key)])
178
- parameters.merge!(param_key => output.value)
179
- end
180
- end
181
- else
182
- remote_stack.outputs.each do |output|
183
- if(param_key = valid_parameters[snake(output.key)])
184
- stack_parameters[param_key][default_key] = output.value
185
- end
186
- end
187
- end
188
- end
189
-
190
- end
191
- end
192
- end
193
-
194
- # Infect miasma
195
- Miasma::Models::Orchestration::Stack.send(:include, KnifeCloudformation::MonkeyPatch::Stack)