knife-cloudformation 0.2.24 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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)