knife-cloudformation 0.2.12 → 0.2.14
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/lib/chef/knife/cloudformation_create.rb +25 -47
- data/lib/chef/knife/cloudformation_destroy.rb +13 -0
- data/lib/chef/knife/cloudformation_update.rb +1 -24
- data/lib/knife-cloudformation/knife/base.rb +17 -4
- data/lib/knife-cloudformation/knife/stack.rb +48 -4
- data/lib/knife-cloudformation/knife/template.rb +2 -2
- data/lib/knife-cloudformation/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b30587ee32086876e78507495f1b16ceff7313c0
|
4
|
+
data.tar.gz: 996465e857261b97b0e5c095793a77a8f95058f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcdf25a7f2ff0749235cf6069c3614e4e01a39464be4d403f64ef886f07c3e060d0930516a99ad24f59c9f6ea1b5971457d69dbfcdc845d016495dbee1e74489
|
7
|
+
data.tar.gz: d91141b3eecffb0a776090e52b88ced51fd87a9bf515763635e11cbdd0a307e4d19b595b2e948626a265bb0d5cbc4e4b2100f0bb60440632e0a37555a41e7974
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## v0.2.14
|
2
|
+
* Pass command configuration through when unpacking
|
3
|
+
* Force stack list reload prior to polling to prevent lookup errors
|
4
|
+
* Add glob support on name arguments provided for `destroy`
|
5
|
+
* Add unpacked stack support to `--apply-stack` flag
|
6
|
+
* Retry events polling when started from different command
|
7
|
+
|
1
8
|
## v0.2.12
|
2
9
|
* Use template to provide logical parameter ordering on stack update
|
3
10
|
* Only set parameters when not the default template value
|
@@ -71,7 +71,7 @@ class Chef
|
|
71
71
|
file = Chef::Config[:knife][:cloudformation][:template]
|
72
72
|
else
|
73
73
|
file = load_template_file
|
74
|
-
|
74
|
+
nested_stacks_unpack = file.delete('sfn_nested_stack')
|
75
75
|
end
|
76
76
|
ui.info "#{ui.color('Cloud Formation:', :bold)} #{ui.color('create', :green)}"
|
77
77
|
stack_info = "#{ui.color('Name:', :bold)} #{name}"
|
@@ -86,12 +86,7 @@ class Chef
|
|
86
86
|
ui.info " -> #{stack_info}"
|
87
87
|
end
|
88
88
|
|
89
|
-
if(
|
90
|
-
|
91
|
-
if(config[:print_only])
|
92
|
-
ui.info _format_json(translate_template(file))
|
93
|
-
exit 0
|
94
|
-
end
|
89
|
+
if(nested_stacks_unpack)
|
95
90
|
|
96
91
|
unpack_nesting(name, file, :create)
|
97
92
|
|
@@ -109,7 +104,7 @@ class Chef
|
|
109
104
|
|
110
105
|
if(config[:print_only])
|
111
106
|
ui.info _format_json(translate_template(stack.template))
|
112
|
-
|
107
|
+
return
|
113
108
|
end
|
114
109
|
|
115
110
|
populate_parameters!(stack.template)
|
@@ -120,48 +115,31 @@ class Chef
|
|
120
115
|
|
121
116
|
end
|
122
117
|
|
123
|
-
if(
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
ui.warn 'Stack state polling has been disabled.'
|
144
|
-
ui.info "Stack creation initialized for #{ui.color(name, :green)}"
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
# Apply any defined remote stacks
|
149
|
-
#
|
150
|
-
# @param stack [Miasma::Models::Orchestration::Stack]
|
151
|
-
# @return [Miasma::Models::Orchestration::Stack]
|
152
|
-
def apply_stacks!(stack)
|
153
|
-
remote_stacks = Chef::Config[:knife][:cloudformation].
|
154
|
-
fetch(:create, {}).fetch(:apply_stacks, [])
|
155
|
-
remote_stacks.each do |stack_name|
|
156
|
-
remote_stack = provider.connection.stacks.get(stack_name)
|
157
|
-
if(remote_stack)
|
158
|
-
stack.apply_stack(remote_stack)
|
118
|
+
if(stack)
|
119
|
+
if(Chef::Config[:knife][:cloudformation][:poll])
|
120
|
+
poll_stack(stack.name)
|
121
|
+
stack = provider.connection.stacks.get(name)
|
122
|
+
|
123
|
+
if(stack.reload.success?)
|
124
|
+
ui.info "Stack create complete: #{ui.color('SUCCESS', :green)}"
|
125
|
+
knife_output = Chef::Knife::CloudformationDescribe.new
|
126
|
+
knife_output.name_args.push(name)
|
127
|
+
knife_output.config[:outputs] = true
|
128
|
+
knife_output.run
|
129
|
+
else
|
130
|
+
ui.fatal "Create of new stack #{ui.color(name, :bold)}: #{ui.color('FAILED', :red, :bold)}"
|
131
|
+
ui.info ""
|
132
|
+
knife_inspect = Chef::Knife::CloudformationInspect.new
|
133
|
+
knife_inspect.name_args.push(name)
|
134
|
+
knife_inspect.config[:instance_failure] = true
|
135
|
+
knife_inspect.run
|
136
|
+
exit 1
|
137
|
+
end
|
159
138
|
else
|
160
|
-
ui.
|
161
|
-
|
139
|
+
ui.warn 'Stack state polling has been disabled.'
|
140
|
+
ui.info "Stack creation initialized for #{ui.color(name, :green)}"
|
162
141
|
end
|
163
142
|
end
|
164
|
-
stack
|
165
143
|
end
|
166
144
|
|
167
145
|
end
|
@@ -21,6 +21,19 @@ class Chef
|
|
21
21
|
def _run
|
22
22
|
stacks = name_args.sort
|
23
23
|
plural = 's' if stacks.size > 1
|
24
|
+
globs = stacks.find_all do |s|
|
25
|
+
s !~ /^[a-zA-Z0-9-]+$/
|
26
|
+
end
|
27
|
+
unless(globs.empty?)
|
28
|
+
glob_stacks = provider.connection.stacks.all.find_all do |remote_stack|
|
29
|
+
globs.detect do |glob|
|
30
|
+
File.fnmatch(glob, remote_stack.name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
stacks += glob_stacks.map(&:name)
|
34
|
+
stacks -= globs
|
35
|
+
stacks.sort!
|
36
|
+
end
|
24
37
|
ui.warn "Destroying Cloud Formation#{plural}: #{ui.color(stacks.join(', '), :bold)}"
|
25
38
|
ui.confirm "Destroy formation#{plural}"
|
26
39
|
stacks.each do |stack_name|
|
@@ -122,6 +122,7 @@ class Chef
|
|
122
122
|
# @param template [Hash] stack template
|
123
123
|
# @param stack [Fog::Orchestration::Stack]
|
124
124
|
# @return [Hash]
|
125
|
+
# @todo to be scrubbed
|
125
126
|
def redefault_stack_parameters(template, stack)
|
126
127
|
stack.parameters.each do |key, value|
|
127
128
|
if(template['Parameters'][key])
|
@@ -131,30 +132,6 @@ class Chef
|
|
131
132
|
template
|
132
133
|
end
|
133
134
|
|
134
|
-
# Apply any defined remote stacks
|
135
|
-
#
|
136
|
-
# @param stack [Miasma::Models::Orchestration::Stack]
|
137
|
-
# @return [Miasma::Models::Orchestration::Stack]
|
138
|
-
def apply_stacks!(stack)
|
139
|
-
remote_stacks = Chef::Config[:knife][:cloudformation].
|
140
|
-
fetch(:update, {}).fetch(:apply_stacks, [])
|
141
|
-
remote_stacks.each do |stack_name|
|
142
|
-
remote_stack = provider.connection.stacks.get(stack_name)
|
143
|
-
if(remote_stack)
|
144
|
-
remote_stack.parameters.each do |key, value|
|
145
|
-
next if Chef::Config[:knife][:cloudformation].fetch(:stacks, {}).fetch(:ignore_parameters, []).include?(key)
|
146
|
-
if(stack.parameters.has_key?(key))
|
147
|
-
stack.parameters[key] = value
|
148
|
-
end
|
149
|
-
end
|
150
|
-
else
|
151
|
-
ui.error "Failed to apply requested stack. Unable to locate. (#{stack_name})"
|
152
|
-
exit 1
|
153
|
-
end
|
154
|
-
end
|
155
|
-
stack
|
156
|
-
end
|
157
|
-
|
158
135
|
end
|
159
136
|
end
|
160
137
|
end
|
@@ -60,10 +60,23 @@ module KnifeCloudformation
|
|
60
60
|
#
|
61
61
|
# @param name [String] name of stack
|
62
62
|
def poll_stack(name)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
retry_attempts = 0
|
64
|
+
begin
|
65
|
+
provider.connection.stacks.reload
|
66
|
+
knife_events = Chef::Knife::CloudformationEvents.new
|
67
|
+
knife_events.name_args.push(name)
|
68
|
+
Chef::Config[:knife][:cloudformation][:poll] = true
|
69
|
+
knife_events.run
|
70
|
+
rescue => e
|
71
|
+
if(retry_attempts < Chef::Config[:knife][:cloudformation].fetch(:max_poll_retries, 5))
|
72
|
+
retry_attempts += 1
|
73
|
+
warn "Unexpected error encountered (#{e.class}: #{e}) Retrying [retry count: #{retry_attempts}]"
|
74
|
+
sleep(1)
|
75
|
+
retry
|
76
|
+
else
|
77
|
+
raise
|
78
|
+
end
|
79
|
+
end
|
67
80
|
end
|
68
81
|
|
69
82
|
# Wrapper for information retrieval. Provides consistent error
|
@@ -8,9 +8,49 @@ module KnifeCloudformation
|
|
8
8
|
|
9
9
|
module InstanceMethods
|
10
10
|
|
11
|
+
# un-packed stack name joiner/identifier
|
12
|
+
UNPACK_NAME_JOINER = '-sfn-'
|
11
13
|
# maximum number of attempts to get valid parameter value
|
12
14
|
MAX_PARAMETER_ATTEMPTS = 5
|
13
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
|
+
if(remote_stack)
|
27
|
+
stack.apply_stack(remote_stack)
|
28
|
+
else
|
29
|
+
apply_unpacked_stack!(stack_name, stack)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
stack
|
33
|
+
end
|
34
|
+
|
35
|
+
# Apply all stacks from an unpacked stack
|
36
|
+
#
|
37
|
+
# @param stack_name [String] name of parent stack
|
38
|
+
# @param stack [Miasma::Models::Orchestration::Stack]
|
39
|
+
# @return [Miasma::Models::Orchestration::Stack]
|
40
|
+
def apply_unpacked_stack!(stack_name, stack)
|
41
|
+
result = provider.connection.stacks.all.find_all do |remote_stack|
|
42
|
+
remote_stack.name.start_with?("#{stack_name}#{UNPACK_NAME_JOINER}")
|
43
|
+
end.sort_by(&:name).map do |remote_stack|
|
44
|
+
stack.apply_stack(remote_stack)
|
45
|
+
end
|
46
|
+
unless(result.empty?)
|
47
|
+
stack
|
48
|
+
else
|
49
|
+
ui.error "Failed to apply requested stack. Unable to locate. (#{stack_name})"
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
14
54
|
# Unpack nested stack and run action on each stack, applying
|
15
55
|
# the previous stacks automatically
|
16
56
|
#
|
@@ -24,20 +64,24 @@ module KnifeCloudformation
|
|
24
64
|
Chef::Config[:knife][:cloudformation][action.to_sym] ||= Mash.new
|
25
65
|
Chef::Config[:knife][:cloudformation][action.to_sym][:apply_stacks] ||= []
|
26
66
|
|
27
|
-
|
67
|
+
orig_options = Chef::Config[:knife][:cloudformation][:options].dup
|
68
|
+
stack_count = 0
|
28
69
|
|
29
70
|
file['Resources'].each do |stack_resource_name, stack_resource|
|
30
71
|
|
31
|
-
nested_stack_name = "#{name}-#{stack_resource_name}"
|
72
|
+
nested_stack_name = "#{name}#{UNPACK_NAME_JOINER}#{stack_count}-#{stack_resource_name}"
|
32
73
|
nested_stack_template = stack_resource['Properties']['Stack']
|
33
|
-
Chef::Config[:knife][:cloudformation][:options]
|
74
|
+
Chef::Config[:knife][:cloudformation][:options] = orig_options.dup
|
34
75
|
|
35
76
|
klass = Chef::Knife.const_get("Cloudformation#{action.to_s.capitalize}")
|
36
77
|
nested_stack_runner = klass.new
|
78
|
+
nested_stack_runner.config = config.dup
|
37
79
|
nested_stack_runner.name_args.push(nested_stack_name)
|
38
80
|
Chef::Config[:knife][:cloudformation][:template] = nested_stack_template
|
39
81
|
nested_stack_runner.run
|
40
|
-
|
82
|
+
unless(config[:print_only])
|
83
|
+
Chef::Config[:knife][:cloudformation][action.to_sym][:apply_stacks].push(nested_stack_name).uniq!
|
84
|
+
end
|
41
85
|
Chef::Config[:knife][:cloudformation][:template] = nil
|
42
86
|
provider.connection.stacks.reload
|
43
87
|
|
@@ -53,9 +53,9 @@ module KnifeCloudformation
|
|
53
53
|
url = URI.parse(file.url)
|
54
54
|
"#{url.scheme}://#{url.host}#{url.path}"
|
55
55
|
end
|
56
|
-
end
|
56
|
+
end
|
57
57
|
else
|
58
|
-
sf.dump
|
58
|
+
sf.dump.merge('sfn_nested_stack' => !!sf.nested?)
|
59
59
|
end
|
60
60
|
else
|
61
61
|
_from_json(File.read(Chef::Config[:knife][:cloudformation][:file]))
|
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.
|
4
|
+
version: 0.2.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Roberts
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef
|