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,206 +0,0 @@
1
- require 'knife-cloudformation'
2
-
3
- class Chef
4
- class Knife
5
- # Cloudformation inspect command
6
- class CloudformationInspect < Knife
7
-
8
- include KnifeCloudformation::Knife::Base
9
- include KnifeCloudformation::Utils::Ssher
10
-
11
- banner 'knife cloudformation inspect NAME'
12
-
13
- option(:attribute,
14
- :short => '-a ATTR',
15
- :long => '--attribute ATTR',
16
- :description => 'Dot delimited attribute to view'
17
- )
18
-
19
- option(:nodes,
20
- :short => '-N',
21
- :long => '--[no-]nodes',
22
- :boolean => true,
23
- :description => 'Locate all instances'
24
- )
25
-
26
- option(:instance_failure,
27
- :short => '-I [LOG_FILE_PATH]',
28
- :long => '--instance-failure [LOG_FILE_PATH]',
29
- :descrption => 'Display chef log file (defaults /var/log/chef/client.log)',
30
- :proc => lambda{|val|
31
- Chef::Config[:knife][:cloudformation][:failure_log_path] = val
32
- }
33
- )
34
-
35
- option(:identity_file,
36
- :short => '-i IDENTITY_FILE',
37
- :long => '--identity-file IDENTITY_FILE',
38
- :description => 'SSH identity file for authentication',
39
- :proc => lambda{|val|
40
- Chef::Config[:knife][:cloudformation][:identity_file] = val
41
- }
42
- )
43
-
44
- option(:ssh_user,
45
- :short => '-x SSH_USER',
46
- :long => '--ssh-user SSH_USER',
47
- :description => 'SSH username for inspection connect',
48
- :proc => lambda{|val|
49
- Chef::Config[:knife][:cloudformation][:ssh_user] = val
50
- }
51
- )
52
-
53
- # Run the stack inspection action
54
- def _run
55
- stack_name = name_args.last
56
- stack = provider.connection.stacks.get(stack_name)
57
- ui.info "Stack inspection #{ui.color(stack_name, :bold)}:"
58
- outputs = [:attribute, :nodes, :instance_failure].map do |key|
59
- if(config.has_key?(key))
60
- send("display_#{key}", stack)
61
- key
62
- end
63
- end.compact
64
- if(outputs.empty?)
65
- ui.info ' Stack dump:'
66
- ui.info MultiJson.dump(
67
- MultiJson.load(
68
- stack.reload.to_json
69
- ),
70
- :pretty => true
71
- )
72
- end
73
- end
74
-
75
- def display_instance_failure(stack)
76
- instances = stack.resources.all.find_all do |resource|
77
- resource.state.to_s.end_with?('failed')
78
- end.map do |resource|
79
- # If compute instance, simply expand
80
- if(resource.within?(:compute, :servers))
81
- resource.instance
82
- # If a waitcondition, check for instance ID
83
- elsif(resource.type.to_s.downcase.end_with?('waitcondition'))
84
- if(resource.status_reason.to_s.include?('uniqueId'))
85
- srv_id = resource.status_reason.split(' ').last.strip
86
- provider.connection.api_for(:compute).servers.get(srv_id)
87
- end
88
- end
89
- end.compact
90
- if(instances.empty?)
91
- ui.error 'Failed to locate any failed instances'
92
- else
93
- log_path = Chef::Config[:knife][:cloudformation][:failure_log_path]
94
- if(log_path.to_s.empty?)
95
- log_path = '/var/log/chef/client.log'
96
- end
97
- opts = ssh_key ? {:keys => [ssh_key]} : {}
98
- instances.each do |instance|
99
- ui.info " -> Log inspect for #{instance.id}:"
100
- address = instance.addresses_public.map do |address|
101
- if(address.version == 4)
102
- address.address
103
- end
104
- end
105
- if(address)
106
- ssh_attempt_users.each do |user|
107
- begin
108
- ui.info remote_file_contents(address.first, user, log_path, opts)
109
- break
110
- rescue Net::SSH::AuthenticationFailed
111
- ui.warn "Authentication failed for user #{user} on instance #{address}"
112
- rescue => e
113
- ui.error "Failed to retrieve log: #{e}"
114
- _debug e
115
- break
116
- end
117
- end
118
- end
119
- end
120
- end
121
- end
122
-
123
- # Users to attempt SSH connection
124
- #
125
- # @return [Array<String>] usernames for ssh connect attempt
126
- def ssh_attempt_users
127
- base_user = Chef::Config[:knife][:cloudformation][:ssh_user] ||
128
- Chef::Config[:knife][:ssh_user] ||
129
- ENV['USER']
130
- [base_user, Chef::Config[:knife][:cloudformation][:ssh_attempt_users]].flatten.compact
131
- end
132
-
133
- def ssh_key
134
- Chef::Config[:knife][:cloudformation][:identity_file] ||
135
- Chef::Config[:knife][:identity_file]
136
- end
137
-
138
- def display_attribute(stack)
139
- attr = config[:attribute].split('.').inject(stack) do |memo, key|
140
- args = key.scan(/\(([^)]*)\)/).flatten.first.to_s
141
- if(args)
142
- args = args.split(',').map{|a| a.to_i.to_s == a ? a.to_i : a}
143
- key = key.split('(').first
144
- end
145
- if(memo.public_methods.include?(key.to_sym))
146
- if(args.size == 1 && args.first.to_s.start_with?('&'))
147
- memo.send(key, &args.first.slice(2, args.first.size).to_sym)
148
- else
149
- memo.send(*[key, args].flatten.compact)
150
- end
151
- else
152
- raise NoMethodError.new "Invalid attribute requested! (#{memo.class}##{key})"
153
- end
154
- end
155
- ui.info " Attribute Lookup -> #{config[:attribute]}:"
156
- ui.info MultiJson.dump(
157
- MultiJson.load(
158
- MultiJson.dump(attr)
159
- ),
160
- :pretty => true
161
- )
162
- end
163
-
164
- def display_nodes(stack)
165
- asg_nodes = Smash[
166
- stack.resources.all.find_all do |resource|
167
- resource.within?(:auto_scale, :groups)
168
- end.map do |group_resource|
169
- asg = group_resource.expand
170
- [
171
- asg.name,
172
- Smash[
173
- asg.servers.map(&:expand).map{|s|
174
- [s.id, Smash.new(
175
- :name => s.name,
176
- :addresses => s.addresses.map(&:address)
177
- )]
178
- }
179
- ]
180
- ]
181
- end
182
- ]
183
- compute_nodes = Smash[
184
- stack.resources.all.find_all do |resource|
185
- resource.within?(:compute, :servers)
186
- end.map do |srv|
187
- srv = srv.instance
188
- [srv.id, Smash.new(
189
- :name => srv.name,
190
- :addresses => srv.addresses.map(&:address)
191
- )]
192
- end
193
- ]
194
- unless(asg_nodes.empty?)
195
- ui.info ' AutoScale Group Instances:'
196
- ui.info MultiJson.dump(asg_nodes, :pretty => true)
197
- end
198
- unless(compute_nodes.empty?)
199
- ui.info ' Compute Instances:'
200
- ui.info MultiJson.dump(compute_nodes, :pretty => true)
201
- end
202
- end
203
-
204
- end
205
- end
206
- end
@@ -1,72 +0,0 @@
1
- require 'knife-cloudformation'
2
-
3
- class Chef
4
- class Knife
5
- # Cloudformation list command
6
- class CloudformationList < Knife
7
-
8
- include KnifeCloudformation::Knife::Base
9
-
10
- banner 'knife cloudformation list NAME'
11
-
12
- option(:attribute,
13
- :short => '-a ATTR',
14
- :long => '--attribute ATTR',
15
- :description => 'Attribute to print. Can be used multiple times.',
16
- :proc => lambda {|val|
17
- Chef::Config[:knife][:cloudformation][:attributes] ||= []
18
- Chef::Config[:knife][:cloudformation][:attributes].push(val).uniq!
19
- }
20
- )
21
-
22
- option(:all,
23
- :long => '--all-attributes',
24
- :description => 'Print all attributes'
25
- )
26
-
27
- option(:status,
28
- :short => '-S STATUS',
29
- :long => '--status STATUS',
30
- :description => 'Match given status. Use "none" to disable. Can be used multiple times.',
31
- :proc => lambda {|val|
32
- Chef::Config[:knife][:cloudformation][:status] ||= []
33
- Chef::Config[:knife][:cloudformation][:status].push(val).uniq!
34
- }
35
- )
36
-
37
- # Run the list command
38
- def _run
39
- things_output(nil, get_list, nil)
40
- end
41
-
42
- # Get the list of stacks to display
43
- #
44
- # @return [Array<Hash>]
45
- def get_list
46
- get_things do
47
- provider.stacks.all.map do |stack|
48
- Mash.new(stack.attributes)
49
- end.sort do |x, y|
50
- if(y[:created].to_s.empty?)
51
- -1
52
- elsif(x[:created].to_s.empty?)
53
- 1
54
- else
55
- Time.parse(y['created'].to_s) <=> Time.parse(x['created'].to_s)
56
- end
57
- end
58
- end
59
- end
60
-
61
- # @return [Array<String>] default attributes to display
62
- def default_attributes
63
- if(provider.connection.provider == :aws)
64
- %w(name created status template_description)
65
- else
66
- %w(name created status description)
67
- end
68
- end
69
-
70
- end
71
- end
72
- end
@@ -1,40 +0,0 @@
1
- require 'knife-cloudformation'
2
-
3
- class Chef
4
- class Knife
5
- class CloudformationPromote < Knife
6
-
7
- include KnifeCloudformation::Knife::Base
8
-
9
- banner 'knife cloudformation promote NEW_STACK_NAME DESTINATION'
10
-
11
- option(:accounts,
12
- :long => '--accounts-file PATH',
13
- :short => '-A PATH',
14
- :description => 'JSON account file',
15
- :proc => lambda{|v|
16
- Chef::Config[:knife][:cloudformation][:promote_accounts] = JSON.load(File.read(v))
17
- }
18
- )
19
-
20
- option(:storage_bucket,
21
- :long => '--exports-bucket NAME',
22
- :description => 'Bucket name containing the exports',
23
- :proc => lambda{|v| Chef::Config[:knife][:cloudformation][:promote_exports_bucket] = v }
24
- )
25
-
26
- option(:storage_prefix,
27
- :long => '--exports-prefix PREFIX',
28
- :description => 'Prefix of stack key',
29
- :proc => lambda{|v| Chef::Config[:knife][:cloudformation][:promote_exports_prefix] = v }
30
- )
31
-
32
-
33
- def _run
34
- stack_name, destination = name_args
35
-
36
- end
37
-
38
- end
39
- end
40
- end
@@ -1,137 +0,0 @@
1
- require 'knife-cloudformation'
2
-
3
- class Chef
4
- class Knife
5
- class CloudformationUpdate < Knife
6
-
7
- include KnifeCloudformation::Knife::Base
8
- include KnifeCloudformation::Knife::Template
9
- include KnifeCloudformation::Knife::Stack
10
-
11
- option(:file_path_prompt,
12
- :long => '--[no-]file-path-prompt',
13
- :description => 'Interactive prompt for template path discovery',
14
- :boolean => true,
15
- :default => false,
16
- :proc => lambda {|val|
17
- Chef::Config[:knife][:cloudformation][:file_path_prompt] = val
18
- }
19
- )
20
- option(:apply_stacks,
21
- :long => '--apply-stack NAME_OR_ID',
22
- :description => 'Autofill parameters using existing stack outputs. Can be used multiple times',
23
- :proc => lambda {|val|
24
- Chef::Config[:knife][:cloudformation][:update] ||= Mash.new
25
- Chef::Config[:knife][:cloudformation][:update][:apply_stacks] ||= []
26
- Chef::Config[:knife][:cloudformation][:update][:apply_stacks].push(val).uniq!
27
- }
28
- )
29
-
30
- banner 'knife cloudformation update NAME'
31
-
32
- # Run the stack creation command
33
- def _run
34
- name = name_args.first
35
- unless(name)
36
- ui.fatal "Formation name must be specified!"
37
- exit 1
38
- end
39
-
40
- stack_info = "#{ui.color('Name:', :bold)} #{name}"
41
-
42
- if(Chef::Config[:knife][:cloudformation][:file])
43
- file = load_template_file
44
- stack_info << " #{ui.color('Path:', :bold)} #{Chef::Config[:knife][:cloudformation][:file]}"
45
- nested_stacks = file.delete('sfn_nested_stack')
46
- end
47
-
48
- if(nested_stacks)
49
-
50
- unpack_nesting(name, file, :update)
51
-
52
- else
53
- stack = provider.connection.stacks.get(name)
54
-
55
- if(stack)
56
- ui.info "#{ui.color('Cloud Formation:', :bold)} #{ui.color('update', :green)}"
57
-
58
- unless(file)
59
- if(Chef::Config[:knife][:cloudformation][:template])
60
- file = Chef::Config[:knife][:cloudformation][:template]
61
- stack_info << " #{ui.color('(template provided)', :green)}"
62
- else
63
- stack_info << " #{ui.color('(no template update)', :yellow)}"
64
- end
65
- end
66
- ui.info " -> #{stack_info}"
67
-
68
- apply_stacks!(stack)
69
-
70
- if(file)
71
- populate_parameters!(file, stack.parameters)
72
- stack.template = translate_template(file)
73
- stack.parameters = Chef::Config[:knife][:cloudformation][:options][:parameters]
74
- stack.template = KnifeCloudformation::Utils::StackParameterScrubber.scrub!(stack.template)
75
- else
76
- populate_parameters!(stack.template, stack.parameters)
77
- stack.parameters = Chef::Config[:knife][:cloudformation][:options][:parameters]
78
- end
79
-
80
- begin
81
- stack.save
82
- rescue Miasma::Error::ApiError::RequestError => e
83
- if(e.message.downcase.include?('no updates')) # :'(
84
- ui.warn "No updates detected for stack (#{stack.name})"
85
- else
86
- raise
87
- end
88
- end
89
-
90
- if(Chef::Config[:knife][:cloudformation][:poll])
91
- poll_stack(stack.name)
92
- if(stack.success?)
93
- ui.info "Stack update complete: #{ui.color('SUCCESS', :green)}"
94
- knife_output = Chef::Knife::CloudformationDescribe.new
95
- knife_output.name_args.push(name)
96
- knife_output.config[:outputs] = true
97
- knife_output.run
98
- else
99
- ui.fatal "Update of stack #{ui.color(name, :bold)}: #{ui.color('FAILED', :red, :bold)}"
100
- ui.info ""
101
- knife_inspect = Chef::Knife::CloudformationInspect.new
102
- knife_inspect.name_args.push(name)
103
- knife_inspect.config[:instance_failure] = true
104
- knife_inspect.run
105
- exit 1
106
- end
107
- else
108
- ui.warn 'Stack state polling has been disabled.'
109
- ui.info "Stack update initialized for #{ui.color(name, :green)}"
110
- end
111
- else
112
- ui.fatal "Failed to locate requested stack: #{ui.color(name, :red, :bold)}"
113
- exit -1
114
- end
115
-
116
- end
117
- end
118
-
119
- # Update default values for parameters in template with
120
- # currently used parameters on the existing stack
121
- #
122
- # @param template [Hash] stack template
123
- # @param stack [Fog::Orchestration::Stack]
124
- # @return [Hash]
125
- # @todo to be scrubbed
126
- def redefault_stack_parameters(template, stack)
127
- stack.parameters.each do |key, value|
128
- if(template['Parameters'][key])
129
- template['Parameters'][key]['Default'] = value
130
- end
131
- end
132
- template
133
- end
134
-
135
- end
136
- end
137
- end