kumogata 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/lib/kumogata/argument_parser.rb +19 -18
- data/lib/kumogata/client.rb +34 -4
- data/lib/kumogata/version.rb +1 -1
- data/spec/kumogata_create_spec.rb +67 -0
- data/spec/kumogata_delete_spec.rb +2 -0
- data/spec/kumogata_update_spec.rb +3 -0
- data/spec/spec_helper.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: 67a5c56f5378acd9da8583d197a558cca8b0d2fb
|
4
|
+
data.tar.gz: 53facba7232603a24adbb060ca8a534035033609
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f442adbf70667594dfee27379892ffb7a1d7334577c4e4f57e91aaa1204c0f8fce5e058dbb5b213c88b24d480da4e2ff4f2b5bd016b6a647535ecfa6e0ee411
|
7
|
+
data.tar.gz: 0484a0ac808e3cb894bb92b1890e8e49005bd20024b62c1e16ec1ac1e68562324ef13d2976e98eb91395bea91c3093348f23aaad1da69370908796ef29778a88
|
data/README.md
CHANGED
@@ -5,8 +5,8 @@
|
|
5
5
|
|
6
6
|
Kumogata is a tool for [AWS CloudFormation](https://aws.amazon.com/cloudformation/).
|
7
7
|
|
8
|
-
[![Gem Version](https://badge.fury.io/rb/kumogata.png?
|
9
|
-
[![Build Status](https://drone.io/github.com/winebarrel/kumogata/status.png?
|
8
|
+
[![Gem Version](https://badge.fury.io/rb/kumogata.png?201403091705)](http://badge.fury.io/rb/kumogata)
|
9
|
+
[![Build Status](https://drone.io/github.com/winebarrel/kumogata/status.png?201403091705)](https://drone.io/github.com/winebarrel/kumogata/latest)
|
10
10
|
|
11
11
|
It can define a template in Ruby DSL, such as:
|
12
12
|
|
@@ -80,6 +80,7 @@ Options:
|
|
80
80
|
-k, --access-key ACCESS_KEY
|
81
81
|
-s, --secret-key SECRET_KEY
|
82
82
|
-r, --region REGION
|
83
|
+
--format TMPLATE_FORMAT
|
83
84
|
--skip-replace-underscore
|
84
85
|
--deletion-policy-retain
|
85
86
|
-p, --parameters KEY_VALUES
|
@@ -76,24 +76,25 @@ class Kumogata::ArgumentParser
|
|
76
76
|
update_usage(opt)
|
77
77
|
|
78
78
|
begin
|
79
|
-
opt.on('-k', '--access-key ACCESS_KEY')
|
80
|
-
opt.on('-s', '--secret-key SECRET_KEY')
|
81
|
-
opt.on('-r', '--region REGION')
|
82
|
-
opt.on('' , '--
|
83
|
-
opt.on('' , '--
|
84
|
-
opt.on('
|
85
|
-
opt.on('-
|
86
|
-
opt.on('',
|
87
|
-
opt.on('', '--
|
88
|
-
opt.on(''
|
89
|
-
opt.on('' , '--
|
90
|
-
opt.on('' , '--
|
91
|
-
opt.on('' , '--
|
92
|
-
opt.on('' , '--
|
93
|
-
opt.on('' , '--
|
94
|
-
opt.on('
|
95
|
-
opt.on(''
|
96
|
-
opt.on('' , '--
|
79
|
+
opt.on('-k', '--access-key ACCESS_KEY') {|v| options[:access_key_id] = v }
|
80
|
+
opt.on('-s', '--secret-key SECRET_KEY') {|v| options[:secret_access_key] = v }
|
81
|
+
opt.on('-r', '--region REGION') {|v| options[:region] = v }
|
82
|
+
opt.on('' , '--format TMPLATE_FORMAT', [:ruby, :json]) {|v| options[:format] = v }
|
83
|
+
opt.on('' , '--skip-replace-underscore') { options[:replace_underscore] = false }
|
84
|
+
opt.on('' , '--deletion-policy-retain') { options[:deletion_policy_retain] = true }
|
85
|
+
opt.on('-p', '--parameters KEY_VALUES', Array) {|v| options[:parameters] = v }
|
86
|
+
opt.on('-e', '--encrypt-parameters KEYS', Array) {|v| options[:encrypt_parameters] = v }
|
87
|
+
opt.on('', '--encryption-password PASS') {|v| options[:encryption_password] = v }
|
88
|
+
opt.on('', '--skip-send-password') { options[:skip_send_password] = true }
|
89
|
+
opt.on('' , '--capabilities CAPABILITIES', Array) {|v| options[:capabilities] = v }
|
90
|
+
opt.on('' , '--disable-rollback') { options[:disable_rollback] = true }
|
91
|
+
opt.on('' , '--notify SNS_TOPICS', Array) {|v| options[:notify] = v }
|
92
|
+
opt.on('' , '--timeout MINUTES', Integer) {|v| options[:timeout] = v }
|
93
|
+
opt.on('' , '--result-log PATH') {|v| options[:result_log] = v }
|
94
|
+
opt.on('' , '--force') { options[:force] = true }
|
95
|
+
opt.on('-w', '--ignore-all-space') { options[:ignore_all_space] = true }
|
96
|
+
opt.on('' , '--no-color') { options[:color] = false }
|
97
|
+
opt.on('' , '--debug') { options[:debug] = true }
|
97
98
|
opt.parse!
|
98
99
|
|
99
100
|
unless (command = ARGV.shift)
|
data/lib/kumogata/client.rb
CHANGED
@@ -107,11 +107,16 @@ class Kumogata::Client
|
|
107
107
|
private ###########################################################
|
108
108
|
|
109
109
|
def open_template(path_or_url)
|
110
|
+
format = @options.format || (ruby_template?(path_or_url) ? :ruby : :json)
|
111
|
+
|
110
112
|
open(path_or_url) do |f|
|
111
|
-
|
113
|
+
case format
|
114
|
+
when :ruby
|
112
115
|
evaluate_template(f)
|
113
|
-
|
116
|
+
when :json
|
114
117
|
JSON.parse(f.read)
|
118
|
+
else
|
119
|
+
raise "Unknown format: #{format}"
|
115
120
|
end
|
116
121
|
end
|
117
122
|
end
|
@@ -324,16 +329,41 @@ class Kumogata::Client
|
|
324
329
|
end
|
325
330
|
|
326
331
|
def while_in_progress(stack, complete_status)
|
332
|
+
event_log = {}
|
333
|
+
|
327
334
|
while stack.status =~ /_IN_PROGRESS\Z/
|
328
|
-
|
335
|
+
print_event_log(stack, event_log)
|
329
336
|
sleep 1
|
330
337
|
end
|
331
338
|
|
339
|
+
print_event_log(stack, event_log)
|
332
340
|
completed = (stack.status == complete_status)
|
333
341
|
Kumogata.logger.info(completed ? 'Successfully' : 'Failed')
|
334
342
|
return completed
|
335
343
|
end
|
336
344
|
|
345
|
+
def print_event_log(stack, event_log)
|
346
|
+
events_for(stack).sort_by {|i| i['Timestamp'] }.each do |event|
|
347
|
+
event_id = event['EventId']
|
348
|
+
|
349
|
+
unless event_log[event_id]
|
350
|
+
event_log[event_id] = event
|
351
|
+
|
352
|
+
timestamp = event['Timestamp']
|
353
|
+
summary = {}
|
354
|
+
|
355
|
+
['LogicalResourceId', 'ResourceStatus', 'ResourceStatusReason'].map do |k|
|
356
|
+
summary[k] = event[k]
|
357
|
+
end
|
358
|
+
|
359
|
+
puts [
|
360
|
+
timestamp.getlocal.strftime('%Y/%m/%d %H:%M:%S %Z'),
|
361
|
+
summary.to_json.colorize_as(:json),
|
362
|
+
].join(': ')
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
337
367
|
def build_create_options
|
338
368
|
opts = {}
|
339
369
|
add_parameters(opts)
|
@@ -377,7 +407,7 @@ class Kumogata::Client
|
|
377
407
|
def update_deletion_policy(template)
|
378
408
|
if @options.delete_stack? or @options.deletion_policy_retain?
|
379
409
|
template['Resources'].each do |k, v|
|
380
|
-
v['DeletionPolicy']
|
410
|
+
v['DeletionPolicy'] ||= 'Retain'
|
381
411
|
end
|
382
412
|
end
|
383
413
|
end
|
data/lib/kumogata/version.rb
CHANGED
@@ -22,6 +22,69 @@ end
|
|
22
22
|
|
23
23
|
run_client(:create, :template => template) do |client, cf|
|
24
24
|
json = eval_template(template, :update_deletion_policy => true).to_json
|
25
|
+
client.should_receive(:print_event_log).twice
|
26
|
+
|
27
|
+
output = make_double('output') do |obj|
|
28
|
+
obj.should_receive(:key) { 'AZ' }
|
29
|
+
obj.should_receive(:value) { 'ap-northeast-1b' }
|
30
|
+
end
|
31
|
+
|
32
|
+
resource_summary = make_double('resource_summary') do |obj|
|
33
|
+
obj.should_receive(:[]).with(:logical_resource_id) { 'myEC2Instance' }
|
34
|
+
obj.should_receive(:[]).with(:physical_resource_id) { 'i-XXXXXXXX' }
|
35
|
+
obj.should_receive(:[]).with(:resource_type) { 'AWS::EC2::Instance' }
|
36
|
+
obj.should_receive(:[]).with(:resource_status) { 'CREATE_COMPLETE' }
|
37
|
+
obj.should_receive(:[]).with(:resource_status_reason) { nil }
|
38
|
+
obj.should_receive(:[]).with(:last_updated_timestamp) { '2014-03-02 04:35:12 UTC' }
|
39
|
+
end
|
40
|
+
|
41
|
+
stack = make_double('stack') do |obj|
|
42
|
+
obj.should_receive(:status).and_return(
|
43
|
+
'CREATE_COMPLETE', 'CREATE_COMPLETE',
|
44
|
+
'DELETE_COMPLETE', 'DELETE_COMPLETE', 'DELETE_COMPLETE')
|
45
|
+
obj.should_receive(:outputs) { [output] }
|
46
|
+
obj.should_receive(:resource_summaries) { [resource_summary] }
|
47
|
+
obj.should_receive(:delete)
|
48
|
+
end
|
49
|
+
|
50
|
+
stacks = make_double('stacks') do |obj|
|
51
|
+
obj.should_receive(:create)
|
52
|
+
.with('kumogata-user-host-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', json, {}) { stack }
|
53
|
+
obj.should_receive(:[])
|
54
|
+
.with('kumogata-user-host-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX') { stack }
|
55
|
+
end
|
56
|
+
|
57
|
+
cf.should_receive(:stacks).twice { stacks }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'create a stack from Ruby template (include DeletionPolicy)' do
|
62
|
+
template = <<-EOS
|
63
|
+
Resources do
|
64
|
+
myEC2Instance do
|
65
|
+
Type "AWS::EC2::Instance"
|
66
|
+
Properties do
|
67
|
+
ImageId "ami-XXXXXXXX"
|
68
|
+
InstanceType "t1.micro"
|
69
|
+
end
|
70
|
+
DeletionPolicy "Delete"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
Outputs do
|
75
|
+
AZ do
|
76
|
+
Value do
|
77
|
+
Fn__GetAtt "myEC2Instance", "AvailabilityZone"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
EOS
|
82
|
+
|
83
|
+
run_client(:create, :template => template) do |client, cf|
|
84
|
+
template = eval_template(template, :update_deletion_policy => true)
|
85
|
+
expect(template['Resources']['myEC2Instance']['DeletionPolicy']).to eq('Delete')
|
86
|
+
json = template.to_json
|
87
|
+
client.should_receive(:print_event_log).twice
|
25
88
|
|
26
89
|
output = make_double('output') do |obj|
|
27
90
|
obj.should_receive(:key) { 'AZ' }
|
@@ -88,6 +151,7 @@ end
|
|
88
151
|
|
89
152
|
run_client(:create, :template => template, :options => {:parameters => {'InstanceType'=>'m1.large'}}) do |client, cf|
|
90
153
|
json = eval_template(template, :update_deletion_policy => true).to_json
|
154
|
+
client.should_receive(:print_event_log).twice
|
91
155
|
|
92
156
|
output = make_double('output') do |obj|
|
93
157
|
obj.should_receive(:key) { 'AZ' }
|
@@ -146,6 +210,7 @@ end
|
|
146
210
|
|
147
211
|
run_client(:create, :arguments => ['MyStack'], :template => template) do |client, cf|
|
148
212
|
json = eval_template(template).to_json
|
213
|
+
client.should_receive(:print_event_log).once
|
149
214
|
|
150
215
|
output = make_double('output') do |obj|
|
151
216
|
obj.should_receive(:key) { 'AZ' }
|
@@ -201,6 +266,7 @@ end
|
|
201
266
|
|
202
267
|
run_client(:create, :arguments => ['MyStack'], :template => template, :options => {:deletion_policy_retain => true}) do |client, cf|
|
203
268
|
json = eval_template(template, :update_deletion_policy => true).to_json
|
269
|
+
client.should_receive(:print_event_log).once
|
204
270
|
|
205
271
|
output = make_double('output') do |obj|
|
206
272
|
obj.should_receive(:key) { 'AZ' }
|
@@ -290,6 +356,7 @@ end
|
|
290
356
|
|
291
357
|
run_client(:create, :template => template, :options => {:parameters => {'InstanceType'=>'m1.large'}, :encrypt_parameters => ['Password']}) do |client, cf|
|
292
358
|
json = eval_template(template, :update_deletion_policy => true, :add_encryption_password => true).to_json
|
359
|
+
client.should_receive(:print_event_log).twice
|
293
360
|
|
294
361
|
output = make_double('output') do |obj|
|
295
362
|
obj.should_receive(:key) { 'AZ' }
|
@@ -1,6 +1,8 @@
|
|
1
1
|
describe 'Kumogata::Client#delete' do
|
2
2
|
it 'update a stack from Ruby template' do
|
3
3
|
run_client(:delete, :arguments => ['MyStack'], :options => {:force => true}) do |client, cf|
|
4
|
+
client.should_receive(:print_event_log).once
|
5
|
+
|
4
6
|
stack = make_double('stack') do |obj|
|
5
7
|
obj.should_receive(:delete).with(no_args())
|
6
8
|
obj.should_receive(:status).and_return(
|
@@ -22,6 +22,7 @@ end
|
|
22
22
|
|
23
23
|
run_client(:update, :arguments => ['MyStack'], :template => template) do |client, cf|
|
24
24
|
json = eval_template(template).to_json
|
25
|
+
client.should_receive(:print_event_log).once
|
25
26
|
|
26
27
|
output = make_double('output') do |obj|
|
27
28
|
obj.should_receive(:key) { 'AZ' }
|
@@ -85,6 +86,7 @@ end
|
|
85
86
|
|
86
87
|
run_client(:update, :arguments => ['MyStack'], :template => template, :options => {:parameters => {'InstanceType'=>'m1.large'}}) do |client, cf|
|
87
88
|
json = eval_template(template).to_json
|
89
|
+
client.should_receive(:print_event_log).once
|
88
90
|
|
89
91
|
output = make_double('output') do |obj|
|
90
92
|
obj.should_receive(:key) { 'AZ' }
|
@@ -173,6 +175,7 @@ end
|
|
173
175
|
|
174
176
|
run_client(:update, :arguments => ['MyStack'], :template => template, :options => {:parameters => {'InstanceType'=>'m1.large'}, :encrypt_parameters => ['Password']}) do |client, cf|
|
175
177
|
json = eval_template(template, :add_encryption_password => true).to_json
|
178
|
+
client.should_receive(:print_event_log).once
|
176
179
|
|
177
180
|
output = make_double('output') do |obj|
|
178
181
|
obj.should_receive(:key) { 'AZ' }
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kumogata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Genki Sugawara
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|