stacker 0.1.0 → 0.2.0
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/lib/stacker/cli.rb +24 -9
- data/lib/stacker/stack.rb +59 -7
- data/lib/stacker/version.rb +1 -1
- metadata +20 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fc55049bd623960704c1fd41806d7cd649e32b7
|
4
|
+
data.tar.gz: a1251cd848cd6fc8e24ed819df0c113e9997757b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bba3693278a33e76d4dba9ffd54e3e355fc01c72a8430aaec6566c38c5570c612b21eccfa537d302d0b5224c84f7e4e5c293c892c71dbc72500593a442ce1c76
|
7
|
+
data.tar.gz: fd29533ef84783f7e303f118ecf15e5dcea095ac0098490c3fd629833dd5db2dd4af9f87fc87e8039ce5840b931167c3cd523f75154f263346d96675873332be
|
data/lib/stacker/cli.rb
CHANGED
@@ -10,8 +10,15 @@ module Stacker
|
|
10
10
|
default_path = ENV['STACKER_PATH'] || '.'
|
11
11
|
default_region = ENV['STACKER_REGION'] || 'us-east-1'
|
12
12
|
|
13
|
-
method_option :path,
|
14
|
-
|
13
|
+
method_option :path, type: :string, default: default_path,
|
14
|
+
banner: 'project path'
|
15
|
+
|
16
|
+
method_option :region, type: :string, default: default_region,
|
17
|
+
banner: 'AWS region name'
|
18
|
+
|
19
|
+
method_option :allow_destructive, type: :boolean, default: false,
|
20
|
+
banner: 'allow destructive updates'
|
21
|
+
|
15
22
|
def initialize(*args); super(*args) end
|
16
23
|
|
17
24
|
desc "init [PATH]", "Create stacker project directories"
|
@@ -63,9 +70,9 @@ module Stacker
|
|
63
70
|
|
64
71
|
if yes? "Update remote template with these changes (y/n)?"
|
65
72
|
time = Benchmark.realtime do
|
66
|
-
stack.update
|
73
|
+
stack.update allow_destructive: options['allow_destructive']
|
67
74
|
end
|
68
|
-
Stacker.logger.info
|
75
|
+
Stacker.logger.info formatted_time stack_name, 'updated', time
|
69
76
|
else
|
70
77
|
Stacker.logger.warn 'Update skipped'
|
71
78
|
end
|
@@ -74,7 +81,7 @@ module Stacker
|
|
74
81
|
time = Benchmark.realtime do
|
75
82
|
stack.create
|
76
83
|
end
|
77
|
-
Stacker.logger.info
|
84
|
+
Stacker.logger.info formatted_time stack_name, 'created', time
|
78
85
|
else
|
79
86
|
Stacker.logger.warn 'Create skipped'
|
80
87
|
end
|
@@ -139,6 +146,10 @@ YAML
|
|
139
146
|
end
|
140
147
|
end
|
141
148
|
|
149
|
+
def formatted_time stack, action, benchmark
|
150
|
+
"Stack #{stack} #{action} in: #{(benchmark / 60).floor} min and #{(benchmark % 60).round} seconds."
|
151
|
+
end
|
152
|
+
|
142
153
|
def full_diff stack
|
143
154
|
templ_diff = stack.template.diff :color
|
144
155
|
param_diff = stack.parameters.diff :color
|
@@ -182,10 +193,6 @@ YAML
|
|
182
193
|
stack.parameters.resolved
|
183
194
|
end
|
184
195
|
|
185
|
-
def time (stack, action, benchmark)
|
186
|
-
return "Stack #{stack} #{action} in: #{(benchmark / 60).floor} min and #{(benchmark % 60).round} seconds."
|
187
|
-
end
|
188
|
-
|
189
196
|
def with_one_or_all stack_name = nil, &block
|
190
197
|
yield_with_stack = proc do |stack|
|
191
198
|
Stacker.logger.info "#{stack.name}:"
|
@@ -199,6 +206,14 @@ YAML
|
|
199
206
|
region.stacks.each(&yield_with_stack)
|
200
207
|
end
|
201
208
|
|
209
|
+
rescue Stacker::Stack::StackPolicyError => err
|
210
|
+
if options['allow_destructive']
|
211
|
+
Stacker.logger.fatal err.message
|
212
|
+
else
|
213
|
+
Stacker.logger.fatal 'Stack update policy prevents replacing or destroying resources.'
|
214
|
+
Stacker.logger.warn 'Try running again with \'--allow-destructive\''
|
215
|
+
end
|
216
|
+
exit 1
|
202
217
|
rescue Stacker::Stack::Error => err
|
203
218
|
Stacker.logger.fatal err.message
|
204
219
|
exit 1
|
data/lib/stacker/stack.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
1
2
|
require 'active_support/core_ext/hash/slice'
|
2
3
|
require 'active_support/core_ext/module/delegation'
|
3
4
|
require 'aws-sdk'
|
@@ -9,10 +10,11 @@ require 'stacker/stack/template'
|
|
9
10
|
module Stacker
|
10
11
|
class Stack
|
11
12
|
|
12
|
-
class Error < StandardError;
|
13
|
+
class Error < StandardError; end
|
14
|
+
class StackPolicyError < Error; end
|
13
15
|
class DoesNotExistError < Error; end
|
14
16
|
class MissingParameters < Error; end
|
15
|
-
class UpToDateError < Error;
|
17
|
+
class UpToDateError < Error; end
|
16
18
|
|
17
19
|
extend Memoist
|
18
20
|
|
@@ -25,6 +27,25 @@ module Stacker
|
|
25
27
|
status_reason
|
26
28
|
]
|
27
29
|
|
30
|
+
SAFE_UPDATE_POLICY = <<-JSON
|
31
|
+
{
|
32
|
+
"Statement" : [
|
33
|
+
{
|
34
|
+
"Effect" : "Deny",
|
35
|
+
"Action" : ["Update:Replace", "Update:Delete"],
|
36
|
+
"Principal" : "*",
|
37
|
+
"Resource" : "*"
|
38
|
+
},
|
39
|
+
{
|
40
|
+
"Effect" : "Allow",
|
41
|
+
"Action" : "Update:*",
|
42
|
+
"Principal" : "*",
|
43
|
+
"Resource" : "*"
|
44
|
+
}
|
45
|
+
]
|
46
|
+
}
|
47
|
+
JSON
|
48
|
+
|
28
49
|
attr_reader :region, :name, :options
|
29
50
|
|
30
51
|
def initialize region, name, options = {}
|
@@ -87,7 +108,12 @@ module Stacker
|
|
87
108
|
raise Error.new err.message
|
88
109
|
end
|
89
110
|
|
90
|
-
def update
|
111
|
+
def update options = {}
|
112
|
+
options.assert_valid_keys(:blocking, :allow_destructive)
|
113
|
+
|
114
|
+
blocking = options.fetch(:blocking, true)
|
115
|
+
allow_destructive = options.fetch(:allow_destructive, false)
|
116
|
+
|
91
117
|
if parameters.missing.any?
|
92
118
|
raise MissingParameters.new(
|
93
119
|
"Required parameters missing: #{parameters.missing.join ', '}"
|
@@ -96,11 +122,17 @@ module Stacker
|
|
96
122
|
|
97
123
|
Stacker.logger.info 'Updating stack'
|
98
124
|
|
99
|
-
|
125
|
+
update_params = {
|
100
126
|
template: template.local,
|
101
127
|
parameters: parameters.resolved,
|
102
128
|
capabilities: capabilities.local
|
103
|
-
|
129
|
+
}
|
130
|
+
|
131
|
+
unless allow_destructive
|
132
|
+
update_params[:stack_policy_during_update_body] = SAFE_UPDATE_POLICY
|
133
|
+
end
|
134
|
+
|
135
|
+
client.update(update_params)
|
104
136
|
|
105
137
|
wait_while_status 'UPDATE_IN_PROGRESS' if blocking
|
106
138
|
rescue AWS::CloudFormation::Errors::ValidationError => err
|
@@ -116,12 +148,32 @@ module Stacker
|
|
116
148
|
|
117
149
|
private
|
118
150
|
|
151
|
+
def report_status
|
152
|
+
case status
|
153
|
+
when /_COMPLETE$/
|
154
|
+
Stacker.logger.info "#{name} Status => #{status}"
|
155
|
+
when /_ROLLBACK_IN_PROGRESS$/
|
156
|
+
failure_event = client.events.enum(limit: 30).find do |event|
|
157
|
+
event.resource_status =~ /_FAILED$/
|
158
|
+
end
|
159
|
+
failure_reason = failure_event.resource_status_reason
|
160
|
+
if failure_reason =~ /stack policy/
|
161
|
+
raise StackPolicyError.new failure_reason
|
162
|
+
else
|
163
|
+
Stacker.logger.fatal "#{name} Status => #{status}"
|
164
|
+
raise Error.new "Failure Reason: #{failure_reason}"
|
165
|
+
end
|
166
|
+
else
|
167
|
+
Stacker.logger.debug "#{name} Status => #{status}"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
119
171
|
def wait_while_status wait_status
|
120
172
|
while flush_cache(:status) && status == wait_status
|
121
|
-
|
173
|
+
report_status
|
122
174
|
sleep 5
|
123
175
|
end
|
124
|
-
|
176
|
+
report_status
|
125
177
|
end
|
126
178
|
|
127
179
|
end
|
data/lib/stacker/version.rb
CHANGED
metadata
CHANGED
@@ -1,125 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stacker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cotap, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: aws-sdk
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: coderay
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.1'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: diffy
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '3.0'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '3.0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: indentation
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0.0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: memoist
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- - ~>
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0.9'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- - ~>
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0.9'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rainbow
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - ~>
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '1.1'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - ~>
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '1.1'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: thor
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - ~>
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0.18'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - ~>
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0.18'
|
125
125
|
- !ruby/object:Gem::Dependency
|
@@ -182,12 +182,12 @@ require_paths:
|
|
182
182
|
- lib
|
183
183
|
required_ruby_version: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- -
|
185
|
+
- - ">="
|
186
186
|
- !ruby/object:Gem::Version
|
187
187
|
version: 1.9.3
|
188
188
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
189
189
|
requirements:
|
190
|
-
- -
|
190
|
+
- - ">="
|
191
191
|
- !ruby/object:Gem::Version
|
192
192
|
version: '0'
|
193
193
|
requirements: []
|