knife-cloudformation 0.2.8 → 0.2.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13b24aa4ad8bd90e9b02f130ee8dc992e657ce1b
4
- data.tar.gz: c1916b7656ed73950454349fb236407c94805013
3
+ metadata.gz: 83a445d83a052179cb88558b3f2b1a159a9c3c6f
4
+ data.tar.gz: e097d47c746572b17f0015be0570754816f83bc6
5
5
  SHA512:
6
- metadata.gz: b3927c0adb0eac79ce40f4468361814cc3cd22d7e50c5003f646164576e12a4180b480a0b3dc7eabd7ee2bc62a44a99234236f78b6e301d733834dbfcc93469f
7
- data.tar.gz: dda8df44d640cb443a66e9757b0535d59d1d164bf3d33306b237063208b34ab9041cda45ca82ad160b311300cc4312080558a7855ada16d277b32fac2ab2d955
6
+ metadata.gz: cb4823fea15e14b41b321f56606788050a2f8b61cc482c9a2637ad49a60da9f4ca0f4245a798c4762318c28b315af70ea189b7e9ff4f64dc3798c2609b231344
7
+ data.tar.gz: a2ded11aad1e6847373b48ed92f21aacb4c357324ff2789538a84ee3eafe044054eccca83404a0d4cc0389fdb9aa9b505a7f0b9cb5038794f9c1946e726cdbec
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## v0.2.10
2
+ * Add initial nested stack support
3
+
1
4
  ## v0.2.8
2
5
  * Update stack lookup implementation to make faster from CLI
3
6
  * Prevent constant error on exception when Redis is not in use
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2014 Heavy Water Operations LLC.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -5,13 +5,14 @@ Gem::Specification.new do |s|
5
5
  s.version = KnifeCloudformation::VERSION.version
6
6
  s.summary = 'Knife tooling for Cloud Formation'
7
7
  s.author = 'Chris Roberts'
8
- s.email = 'chrisroberts.code@gmail.com'
9
- s.homepage = 'http://github.com/heavywater/knife-cloudformation'
8
+ s.email = 'code@chrisroberts.org'
9
+ s.homepage = 'http://github.com/hw-labs/knife-cloudformation'
10
10
  s.description = 'Knife tooling for Cloud Formation'
11
+ s.license = 'Apache-2.0'
11
12
  s.require_path = 'lib'
12
13
  s.add_dependency 'chef'
13
14
  s.add_dependency 'miasma'
14
15
  s.add_dependency 'net-ssh'
15
16
  s.add_dependency 'sparkle_formation', '~> 0.2.0'
16
- s.files = Dir['lib/**/*'] + %w(knife-cloudformation.gemspec README.md CHANGELOG.md)
17
+ s.files = Dir['lib/**/*'] + %w(knife-cloudformation.gemspec README.md CHANGELOG.md LICENSE)
17
18
  end
@@ -100,6 +100,10 @@ class Chef
100
100
  exit 0
101
101
  end
102
102
 
103
+ # TODO: if nested stacks and not extracted (based on config
104
+ # option, break resources out and iterate each stack and use
105
+ # apply-stack as we iterate the list
106
+
103
107
  populate_parameters!(stack.template)
104
108
  stack.parameters = Chef::Config[:knife][:cloudformation][:options][:parameters]
105
109
 
@@ -26,6 +26,7 @@ class Chef
26
26
  stacks.each do |stack_name|
27
27
  stack = provider.connection.stacks.get(stack_name)
28
28
  if(stack)
29
+ nested_stack_cleanup!(stack)
29
30
  stack.destroy
30
31
  else
31
32
  ui.warn "Failed to locate requested stack: #{ui.color(stack_name, :bold)}"
@@ -41,6 +42,30 @@ class Chef
41
42
  ui.info " -> Destroyed Cloud Formation#{plural}: #{ui.color(stacks.join(', '), :bold, :red)}"
42
43
  end
43
44
 
45
+ # Cleanup persisted templates if nested stack resources are included
46
+ def nested_stack_cleanup!(stack)
47
+ nest_stacks = stack.template.fetch('Resources', {}).values.find_all do |resource|
48
+ resource['Type'] == 'AWS::CloudFormation::Stack'
49
+ end.each do |resource|
50
+ url = resource['Properties']['TemplateURL']
51
+ if(url)
52
+ _, bucket_name, path = URI.parse(url).path.split('/', 3)
53
+ bucket = provider.connection.api_for(:storage).buckets.get(bucket_name)
54
+ if(bucket)
55
+ file = bucket.files.get(path)
56
+ if(file)
57
+ file.destroy
58
+ ui.info "Deleted nested stack template! (Bucket: #{bucket_name} Template: #{path})"
59
+ else
60
+ ui.warn "Failed to locate template file within bucket for deletion! (#{path})"
61
+ end
62
+ else
63
+ ui.warn "Failed to locate bucket containing template file for deletion! (#{bucket_name})"
64
+ end
65
+ end
66
+ end
67
+ end
68
+
44
69
  end
45
70
  end
46
71
  end
@@ -56,13 +56,27 @@ class Chef
56
56
  cycle_events = true
57
57
  while(cycle_events)
58
58
  cycle_events = stack.in_progress?
59
- sleep(Chef::Config[:knife][:cloudformation][:poll_delay] || 15)
59
+ sleep(Chef::Config[:knife][:cloudformation][:poll_delay] || 10)
60
60
  stack.events.reload
61
61
  events = get_events(stack, last_id)
62
62
  unless(events.empty?)
63
63
  last_id = events.last[:id]
64
64
  things_output(nil, events, 'events', :no_title, :ignore_empty_output)
65
65
  end
66
+ nest_stacks = stack.resources.all.find_all do |resource|
67
+ resource.state.to_s.end_with?('in_progress') &&
68
+ resource.type == 'AWS::CloudFormation::Stack'
69
+ end
70
+ if(nest_stacks)
71
+ nest_stacks.each do |nest_stack|
72
+ begin
73
+ poll_stack(nest_stack.id)
74
+ ui.info "Complete event listing for nested stack (#{nest_stack.name})"
75
+ rescue => e
76
+ ui.warn "Error encountered on event listing for nested stack - #{e} (#{nest_stack.name})"
77
+ end
78
+ end
79
+ end
66
80
  stack.reload
67
81
  end
68
82
  # Extra to see completion
@@ -70,7 +84,7 @@ class Chef
70
84
  end
71
85
  else
72
86
  ui.fatal "Failed to locate requested stack: #{ui.color(name, :bold, :red)}"
73
- exit -1
87
+ raise "Failed to locate stack: #{name}!"
74
88
  end
75
89
  end
76
90
 
@@ -41,10 +41,10 @@ class Chef
41
41
 
42
42
  if(stack)
43
43
  ui.info "#{ui.color('Cloud Formation:', :bold)} #{ui.color('update', :green)}"
44
- file = load_template_file(:allow_missing)
45
44
  stack_info = "#{ui.color('Name:', :bold)} #{name}"
46
45
 
47
46
  if(Chef::Config[:knife][:cloudformation][:file])
47
+ file = load_template_file
48
48
  stack_info << " #{ui.color('Path:', :bold)} #{Chef::Config[:knife][:cloudformation][:file]}"
49
49
  else
50
50
  stack_info << " #{ui.color('(no temlate update)', :yellow)}"
@@ -54,10 +54,8 @@ class Chef
54
54
  apply_stacks!(stack)
55
55
 
56
56
  if(file)
57
- redefault_stack_parameters(file, stack)
58
- populate_parameters!(file)
59
- file = translate_template(file)
60
- stack.template = file
57
+ stack_parameters_update!(stack)
58
+ stack.template = translate_template(file)
61
59
  stack.parameters = Chef::Config[:knife][:cloudformation][:parameters]
62
60
  else
63
61
  stack_parameters_update!(stack)
@@ -138,7 +138,7 @@ module KnifeCloudformation
138
138
  Chef::Config[:knife][:cloudformation][:credentials] ||= Mash.new
139
139
  Chef::Config[:knife][:cloudformation][:options] ||= Mash.new
140
140
  Chef::Config[:knife][:cloudformation][:ignore_parameters] = []
141
- %w(poll interactive_parameters).each do |key|
141
+ %w(poll interactive_parameters apply_nesting).each do |key|
142
142
  if(Chef::Config[:knife][:cloudformation][key].nil?)
143
143
  Chef::Config[:knife][:cloudformation][key] = true
144
144
  end
@@ -29,7 +29,30 @@ module KnifeCloudformation
29
29
  Chef::Config[:knife][:cloudformation][:template]
30
30
  elsif(Chef::Config[:knife][:cloudformation][:file])
31
31
  if(Chef::Config[:knife][:cloudformation][:processing])
32
- SparkleFormation.compile(Chef::Config[:knife][:cloudformation][:file])
32
+ sf = SparkleFormation.compile(Chef::Config[:knife][:cloudformation][:file], :sparkle)
33
+ if(sf.nested? && Chef::Config[:knife][:cloudformation][:apply_nesting])
34
+ sf.apply_nesting do |stack_name, stack_definition|
35
+ bucket = provider.connection.api_for(:storage).buckets.get(
36
+ Chef::Config[:knife][:cloudformation][:nesting_bucket]
37
+ )
38
+ unless(bucket)
39
+ raise "Failed to locate configured bucket for stack template storage (#{bucket})!"
40
+ end
41
+ file = bucket.files.build
42
+ file.name = "#{name_args.first}_#{stack_name}.json"
43
+ file.content_type = 'text/json'
44
+ file.body = MultiJson.dump(KnifeCloudformation::Utils::StackParameterScrubber.scrub!(stack_definition))
45
+ file.save
46
+ # TODO: what if we need extra params?
47
+ url = URI.parse(file.url)
48
+ "#{url.scheme}://#{url.host}#{url.path}"
49
+ end
50
+ else
51
+ if(sf.nested? && !sf.isolated_nests?)
52
+ raise TypeError.new('Template does not contain isolated stack nesting! Cannot process in existing state.')
53
+ end
54
+ sf.dump
55
+ end
33
56
  else
34
57
  _from_json(File.read(Chef::Config[:knife][:cloudformation][:file]))
35
58
  end
@@ -162,6 +185,18 @@ module KnifeCloudformation
162
185
  :description => 'Chunk length for serialization',
163
186
  :proc => lambda {|val| Chef::Config[:knife][:cloudformation][:translate_chunk_size] = val}
164
187
  )
188
+ option(:apply_nesting,
189
+ :long => '--[no-]apply-nesting',
190
+ :description => 'Apply stack nesting',
191
+ :default => false,
192
+ :boolean => true,
193
+ :proc => lambda{|val| Chef::Config[:knife][:cloudformation][:apply_nesting] = val}
194
+ )
195
+ option(:nesting_bucket,
196
+ :long => '--nesting-bucket',
197
+ :description => 'Bucket to use for storing nested stack templates',
198
+ :proc => lambda{|val| Chef::Config[:knife][:cloudformation][:nesting_bucket] = val}
199
+ )
165
200
 
166
201
  Chef::Config[:knife][:cloudformation][:file_path_prompt] = true
167
202
 
@@ -1,4 +1,4 @@
1
1
  module KnifeCloudformation
2
2
  # Current library version
3
- VERSION = Gem::Version.new('0.2.8')
3
+ VERSION = Gem::Version.new('0.2.10')
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-cloudformation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Roberts
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-11 00:00:00.000000000 Z
11
+ date: 2014-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chef
@@ -67,12 +67,13 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.2.0
69
69
  description: Knife tooling for Cloud Formation
70
- email: chrisroberts.code@gmail.com
70
+ email: code@chrisroberts.org
71
71
  executables: []
72
72
  extensions: []
73
73
  extra_rdoc_files: []
74
74
  files:
75
75
  - CHANGELOG.md
76
+ - LICENSE
76
77
  - README.md
77
78
  - knife-cloudformation.gemspec
78
79
  - lib/chef/knife/cloudformation_create.rb
@@ -107,8 +108,9 @@ files:
107
108
  - lib/knife-cloudformation/utils/stack_parameter_scrubber.rb
108
109
  - lib/knife-cloudformation/utils/stack_parameter_validator.rb
109
110
  - lib/knife-cloudformation/version.rb
110
- homepage: http://github.com/heavywater/knife-cloudformation
111
- licenses: []
111
+ homepage: http://github.com/hw-labs/knife-cloudformation
112
+ licenses:
113
+ - Apache-2.0
112
114
  metadata: {}
113
115
  post_install_message:
114
116
  rdoc_options: []