kumogata 0.3.2 → 0.3.3

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: baf7b8cbddd815d7f08705918dcb9bba0f426345
4
- data.tar.gz: d8df685f3891d4266da07997a2926a4a33083dfc
3
+ metadata.gz: 67a5c56f5378acd9da8583d197a558cca8b0d2fb
4
+ data.tar.gz: 53facba7232603a24adbb060ca8a534035033609
5
5
  SHA512:
6
- metadata.gz: 7b36d2411bdd49f4b2031efa2c45fd4f8fbd30591857c85098b1f004805b6e5cbe6615fccbfa998cc5e62becd5bd3a2324adbaf211848df68c19f7341097da94
7
- data.tar.gz: 0ad0e636569b330cb22849a41c2728c0b2419767d170e26225633069274b6cdb0b01a00be168003e2f066bbf4bd02ba2a5eb90362be0f61975115196aeb9908c
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?201403082134)](http://badge.fury.io/rb/kumogata)
9
- [![Build Status](https://drone.io/github.com/winebarrel/kumogata/status.png?201403082134)](https://drone.io/github.com/winebarrel/kumogata/latest)
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') {|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('' , '--skip-replace-underscore') { options[:replace_underscore] = false }
83
- opt.on('' , '--deletion-policy-retain') { options[:deletion_policy_retain] = true }
84
- opt.on('-p', '--parameters KEY_VALUES', Array) {|v| options[:parameters] = v }
85
- opt.on('-e', '--encrypt-parameters KEYS', Array) {|v| options[:encrypt_parameters] = v }
86
- opt.on('', '--encryption-password PASS') {|v| options[:encryption_password] = v }
87
- opt.on('', '--skip-send-password') { options[:skip_send_password] = true }
88
- opt.on('' , '--capabilities CAPABILITIES', Array) {|v| options[:capabilities] = v }
89
- opt.on('' , '--disable-rollback') { options[:disable_rollback] = true }
90
- opt.on('' , '--notify SNS_TOPICS', Array) {|v| options[:notify] = v }
91
- opt.on('' , '--timeout MINUTES', Integer) {|v| options[:timeout] = v }
92
- opt.on('' , '--result-log PATH') {|v| options[:result_log] = v }
93
- opt.on('' , '--force') { options[:force] = true }
94
- opt.on('-w', '--ignore-all-space') { options[:ignore_all_space] = true }
95
- opt.on('' , '--no-color') { options[:color] = false }
96
- opt.on('' , '--debug') { options[:debug] = true }
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)
@@ -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
- if ruby_template?(path_or_url)
113
+ case format
114
+ when :ruby
112
115
  evaluate_template(f)
113
- else
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
- print '.'.intense_black unless @options.debug?
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'] = 'Retain'
410
+ v['DeletionPolicy'] ||= 'Retain'
381
411
  end
382
412
  end
383
413
  end
@@ -1,3 +1,3 @@
1
1
  module Kumogata
2
- VERSION = '0.3.2'
2
+ VERSION = '0.3.3'
3
3
  end
@@ -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
@@ -80,7 +80,7 @@ end
80
80
 
81
81
  def update_deletion_policy(template)
82
82
  template['Resources'].each do |k, v|
83
- v['DeletionPolicy'] = 'Retain'
83
+ v['DeletionPolicy'] ||= 'Retain'
84
84
  end
85
85
  end
86
86
 
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.2
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-08 00:00:00.000000000 Z
11
+ date: 2014-03-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk