kumogata 0.4.11 → 0.4.12

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: 7537f25fa6ed9e22a4c12d03cac0a00ec783801e
4
- data.tar.gz: e325a318da75a8be3ef42a8ef89353c71bf95291
3
+ metadata.gz: 60b666d69792655cd9d5f1ef9b67d8bc73aa1801
4
+ data.tar.gz: b40df1b37bad8bc10c9fa2f680324fad09ada144
5
5
  SHA512:
6
- metadata.gz: 1802d2a36f631d1130b2e8471e12ead569363ffee7dfa99c41b23b45c6affc15dfca2c3ab0385a661fab81778df147356533440e9504d568a79964cc69a368a2
7
- data.tar.gz: 03203252527136f4626c658550ab5f3775e0db76ffe80455b721ccd399fd77cf5adb4554652f3ce7b3af9fffa32729ea4205279d1ff0b14ed3a7c2cf5e86958c
6
+ metadata.gz: 0d1acf88ed630a8ecba7cfa15ac2b8503d128ee9dcb9617cfea4eba019f1047e1548bd4c84c26b1c4909846b782a547cd8c4d8477969b1f7fe746eb83538ef6b
7
+ data.tar.gz: 5647c1968838158a41bf6568842074cfeed764a8471737454ffe645f658eca9cfde5fb201252efa97cbe470753c97015d553c2afc00c433f1adb9a5ae8ae308d
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?201404191738)](http://badge.fury.io/rb/kumogata)
9
- [![Build Status](https://drone.io/github.com/winebarrel/kumogata/status.png?201404191738)](https://drone.io/github.com/winebarrel/kumogata/latest)
8
+ [![Gem Version](https://badge.fury.io/rb/kumogata.png?201404231403)](http://badge.fury.io/rb/kumogata)
9
+ [![Build Status](https://drone.io/github.com/winebarrel/kumogata/status.png?201404231403)](https://drone.io/github.com/winebarrel/kumogata/latest)
10
10
 
11
11
  It can define a template in Ruby DSL, such as:
12
12
 
@@ -281,6 +281,32 @@ Resources do
281
281
  end # Resources
282
282
  ```
283
283
 
284
+ ## Iteration
285
+
286
+ You can use the Iteration in the template using `_(...)` method.
287
+
288
+ ```ruby
289
+ Resources do
290
+ ['instance1', 'instance2', 'instance3'].echo {|instance_name|
291
+ _(instance_name) do
292
+ Type "AWS::EC2::Instance"
293
+ Properties do
294
+ ImageId "ami-XXXXXXXX"
295
+ InstanceType { Ref "InstanceType" }
296
+ KeyName "your_key_name"
297
+
298
+ UserData (<<-EOS).undent.encode64
299
+ #!/bin/bash
300
+ yum install -y httpd
301
+ service httpd start
302
+ hostname #{instance_name}
303
+ EOS
304
+ end
305
+ end
306
+ }
307
+ end
308
+ ```
309
+
284
310
  ## Post command
285
311
 
286
312
  You can run shell/ssh commands after building servers using `_post()`.
@@ -340,7 +366,7 @@ Status: 0
340
366
 
341
367
  ## YAML template
342
368
 
343
- You can also use the template YAML instead of JSON and Ruby.
369
+ You can also use the YAML template instead of JSON and Ruby.
344
370
 
345
371
  ```yaml
346
372
  ---
@@ -384,6 +410,36 @@ Outputs:
384
410
 
385
411
  $ kumogata convert Drupal_Single_Instance.template --output-format=yaml
386
412
 
413
+ ## Outputs Filter
414
+
415
+ ```ruby
416
+ Outputs do
417
+ MyPublicIp do
418
+ Value { Fn__GetAtt "MyInstance", "PublicIp" }
419
+ end
420
+ end
421
+
422
+ _outputs_filter do |output|
423
+ outputs["PublicIp"].gsub!('.', '_')
424
+ # PublicIp: XXX.XXX.XXX.XXX => XXX-XXX-XXX-XXX
425
+ end
426
+
427
+ _post do
428
+ ...
429
+ end
430
+ ```
431
+
432
+ ## Configuration File
433
+
434
+ Kumogata supports [aws-cli configuration file](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-waitcondition.html).
435
+
436
+ ```
437
+ [default]
438
+ aws_access_key_id=AKIAIOSFODNN7EXAMPLE
439
+ aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
440
+ aws_security_token=texample123324
441
+ ```
442
+
387
443
  ## Demo
388
444
 
389
445
  * Create resources
@@ -15,6 +15,7 @@ class Kumogata::Client
15
15
  add_encryption_password(template)
16
16
 
17
17
  outputs = create_stack(template, stack_name)
18
+ filter_outputs(template, outputs)
18
19
  @post_processing.run(:create, outputs)
19
20
 
20
21
  outputs
@@ -58,6 +59,7 @@ class Kumogata::Client
58
59
  add_encryption_password(template)
59
60
 
60
61
  outputs = update_stack(template, stack_name)
62
+ filter_outputs(template, outputs)
61
63
  @post_processing.run(:update, outputs)
62
64
 
63
65
  outputs
@@ -262,6 +264,10 @@ class Kumogata::Client
262
264
  @__hash__[path] = value
263
265
  end
264
266
 
267
+ def _outputs_filter(&block)
268
+ @__hash__[:_outputs_filter] = block
269
+ end
270
+
265
271
  def _post(options = {}, &block)
266
272
  commands = Dslh::ScopeBlock.nest(binding, 'block')
267
273
 
@@ -618,4 +624,12 @@ EOS
618
624
  raise "1 validation error detected: Value '#{stack_name}' at 'stackName' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-zA-Z][-a-zA-Z0-9]*"
619
625
  end
620
626
  end
627
+
628
+ def filter_outputs(template, outputs)
629
+ if (_outputs_filter = template.delete(:_outputs_filter))
630
+ _outputs_filter.call(outputs)
631
+ end
632
+
633
+ return outputs
634
+ end
621
635
  end
@@ -1,3 +1,3 @@
1
1
  module Kumogata
2
- VERSION = '0.4.11'
2
+ VERSION = '0.4.12'
3
3
  end
@@ -262,6 +262,98 @@ end
262
262
  end
263
263
  end
264
264
 
265
+ it 'create a stack from Ruby template and run ssh command (modify outputs)' do
266
+ template = <<-TEMPLATE
267
+ Resources do
268
+ myEC2Instance do
269
+ Type "AWS::EC2::Instance"
270
+ Properties do
271
+ ImageId "ami-XXXXXXXX"
272
+ InstanceType "t1.micro"
273
+ end
274
+ end
275
+ end
276
+
277
+ Outputs do
278
+ PublicIp do
279
+ Value do
280
+ Fn__GetAtt "myEC2Instance", "PublicIp"
281
+ end
282
+ end
283
+ end
284
+
285
+ _outputs_filter do |outputs|
286
+ outputs['MyOutput'] = 100
287
+ end
288
+
289
+ _post do
290
+ ssh_command do
291
+ ssh do
292
+ host { Key "PublicIp" }
293
+ user "ec2-user"
294
+ end
295
+ command <<-EOS
296
+ ls
297
+ EOS
298
+ end
299
+ end
300
+ TEMPLATE
301
+
302
+ run_client(:create, :template => template) do |client, cf|
303
+ json = eval_template(template, :update_deletion_policy => true).to_json
304
+ client.should_receive(:print_event_log).twice
305
+ client.should_receive(:create_event_log).once
306
+
307
+ output = make_double('output') do |obj|
308
+ obj.should_receive(:key) { 'PublicIp' }
309
+ obj.should_receive(:value) { '127.0.0.1' }
310
+ end
311
+
312
+ resource_summary = make_double('resource_summary') do |obj|
313
+ obj.should_receive(:[]).with(:logical_resource_id) { 'myEC2Instance' }
314
+ obj.should_receive(:[]).with(:physical_resource_id) { 'i-XXXXXXXX' }
315
+ obj.should_receive(:[]).with(:resource_type) { 'AWS::EC2::Instance' }
316
+ obj.should_receive(:[]).with(:resource_status) { 'CREATE_COMPLETE' }
317
+ obj.should_receive(:[]).with(:resource_status_reason) { nil }
318
+ obj.should_receive(:[]).with(:last_updated_timestamp) { '2014-03-02 04:35:12 UTC' }
319
+ end
320
+
321
+ stack = make_double('stack') do |obj|
322
+ obj.should_receive(:status).and_return(
323
+ 'CREATE_COMPLETE', 'CREATE_COMPLETE',
324
+ 'DELETE_COMPLETE', 'DELETE_COMPLETE', 'DELETE_COMPLETE')
325
+ obj.should_receive(:outputs) { [output] }
326
+ obj.should_receive(:resource_summaries) { [resource_summary] }
327
+ obj.should_receive(:delete)
328
+ end
329
+
330
+ stacks = make_double('stacks') do |obj|
331
+ obj.should_receive(:create)
332
+ .with('kumogata-user-host-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX', json, {}) { stack }
333
+ obj.should_receive(:[])
334
+ .with('kumogata-user-host-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX') { stack }
335
+ end
336
+
337
+ cf.should_receive(:stacks).twice { stacks }
338
+
339
+ client.instance_variable_get(:@post_processing)
340
+ .should_receive(:run_ssh_command)
341
+ .with({"host"=>"<%= Key \"PublicIp\" %>", "user"=>"ec2-user", "request_pty"=>true}, " ls\n", {"PublicIp"=>"127.0.0.1", "MyOutput"=>100})
342
+ .and_return(["file1\nfile2\n", "", 0])
343
+
344
+ client.instance_variable_get(:@post_processing)
345
+ .should_receive(:print_command).with('ssh_command')
346
+
347
+ client.instance_variable_get(:@post_processing)
348
+ .should_receive(:print_command_result)
349
+ .with("file1\nfile2\n", "", 0)
350
+
351
+ client.instance_variable_get(:@post_processing)
352
+ .should_receive(:save_command_results)
353
+ .with([{'ssh_command' => {'ExitStatus' => 0, 'StdOut' => "file1\nfile2\n", 'StdErr' => ""}}])
354
+ end
355
+ end
356
+
265
357
  it 'create a stack from Ruby template and run command (specifies timing)' do
266
358
  template = <<-TEMPLATE
267
359
  Resources do
@@ -299,6 +299,96 @@ end
299
299
  end
300
300
  end
301
301
 
302
+ it 'update a stack from Ruby template and run ssh command (modify outputs)' do
303
+ template = <<-TEMPLATE
304
+ Resources do
305
+ myEC2Instance do
306
+ Type "AWS::EC2::Instance"
307
+ Properties do
308
+ ImageId "ami-XXXXXXXX"
309
+ InstanceType "t1.micro"
310
+ end
311
+ end
312
+ end
313
+
314
+ Outputs do
315
+ PublicIp do
316
+ Value do
317
+ Fn__GetAtt "myEC2Instance", "PublicIp"
318
+ end
319
+ end
320
+ end
321
+
322
+ _outputs_filter do |outputs|
323
+ outputs['PublicIp'].gsub!('.', '-')
324
+ end
325
+
326
+ _post do
327
+ ssh_command do
328
+ after :update
329
+ ssh do
330
+ host { Key "PublicIp" }
331
+ user "ec2-user"
332
+ end
333
+ command <<-EOS
334
+ ls
335
+ EOS
336
+ end
337
+ end
338
+ TEMPLATE
339
+
340
+ run_client(:update, :arguments => ['MyStack'], :template => template) do |client, cf|
341
+ json = eval_template(template).to_json
342
+ client.should_receive(:print_event_log).once
343
+ client.should_receive(:create_event_log).once
344
+
345
+ output = make_double('output') do |obj|
346
+ obj.should_receive(:key) { 'PublicIp' }
347
+ obj.should_receive(:value) { '127.0.0.1' }
348
+ end
349
+
350
+ resource_summary = make_double('resource_summary') do |obj|
351
+ obj.should_receive(:[]).with(:logical_resource_id) { 'myEC2Instance' }
352
+ obj.should_receive(:[]).with(:physical_resource_id) { 'i-XXXXXXXX' }
353
+ obj.should_receive(:[]).with(:resource_type) { 'AWS::EC2::Instance' }
354
+ obj.should_receive(:[]).with(:resource_status) { 'UPDATE_COMPLETE' }
355
+ obj.should_receive(:[]).with(:resource_status_reason) { nil }
356
+ obj.should_receive(:[]).with(:last_updated_timestamp) { '2014-03-02 04:35:12 UTC' }
357
+ end
358
+
359
+ stack = make_double('stack') do |obj|
360
+ obj.should_receive(:update).with(:template => json)
361
+ obj.should_receive(:status).and_return(
362
+ 'UPDATE_COMPLETE', 'UPDATE_COMPLETE', 'UPDATE_COMPLETE')
363
+ obj.should_receive(:outputs) { [output] }
364
+ obj.should_receive(:resource_summaries) { [resource_summary] }
365
+ end
366
+
367
+ stacks = make_double('stacks') do |obj|
368
+ obj.should_receive(:[])
369
+ .with('MyStack') { stack }
370
+ end
371
+
372
+ cf.should_receive(:stacks) { stacks }
373
+
374
+ client.instance_variable_get(:@post_processing)
375
+ .should_receive(:run_ssh_command)
376
+ .with({"host"=>"<%= Key \"PublicIp\" %>", "user"=>"ec2-user", "request_pty"=>true}, " ls\n", {"PublicIp"=>"127-0-0-1"})
377
+ .and_return(["file1\nfile2\n", "", 0])
378
+
379
+ client.instance_variable_get(:@post_processing)
380
+ .should_receive(:print_command).with('ssh_command')
381
+
382
+ client.instance_variable_get(:@post_processing)
383
+ .should_receive(:print_command_result)
384
+ .with("file1\nfile2\n", "", 0)
385
+
386
+ client.instance_variable_get(:@post_processing)
387
+ .should_receive(:save_command_results)
388
+ .with([{'ssh_command' => {'ExitStatus' => 0, 'StdOut' => "file1\nfile2\n", 'StdErr' => ""}}])
389
+ end
390
+ end
391
+
302
392
  it 'update a stack from Ruby template and run command (specifies timing)' do
303
393
  template = <<-TEMPLATE
304
394
  Resources do
data/spec/spec_helper.rb CHANGED
@@ -35,6 +35,12 @@ def tempfile(content, template_ext)
35
35
  end
36
36
  end
37
37
 
38
+ class Proc
39
+ def to_s
40
+ "<Proc Object>"
41
+ end
42
+ end
43
+
38
44
  def run_client(command, options = {})
39
45
  $stdout = open('/dev/null', 'w') unless ENV['DEBUG']
40
46
 
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.4.11
4
+ version: 0.4.12
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-04-19 00:00:00.000000000 Z
11
+ date: 2014-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -326,4 +326,3 @@ test_files:
326
326
  - spec/kumogata_validate_spec.rb
327
327
  - spec/spec_helper.rb
328
328
  - spec/string_stream_spec.rb
329
- has_rdoc: