knife-cloudformation 0.2.12 → 0.2.14
Sign up to get free protection for your applications and to get access to all the features.
- 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
|