cloudster 2.18.0 → 2.19.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.
data/README.md CHANGED
@@ -93,6 +93,10 @@ Cloudster can also interact with the provisioned AWS Cloud :
93
93
 
94
94
  cloud.delete(:stack_name => 'TestStack')
95
95
 
96
+ - Get the output attributes of each resource in the stack :
97
+
98
+ cloud.outputs(:stack_name => 'TestStack')
99
+
96
100
  - Describe the events of a stack :
97
101
 
98
102
  cloud.events(:stack_name => 'TestStack')
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.18.0
1
+ 2.19.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cloudster"
8
- s.version = "2.18.0"
8
+ s.version = "2.19.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Emil Soman"]
12
- s.date = "2013-01-08"
12
+ s.date = "2013-01-10"
13
13
  s.description = "Cloudster is a Ruby gem that was born to cut the learning curve involved \n in writing your own CloudFormation templates. If you don't know what a CloudFormation template is, \n but know about the AWS Cloud offerings, you can still use cloudster to provision your stack. \n Still in infancy , cloudster can create a very basic stack like a breeze. All kinds of contribution welcome !"
14
14
  s.email = "emil.soman@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -1,6 +1,7 @@
1
1
  module Cloudster
2
2
  #Cloud objects have many resources. This class can generate the cloudformation template and provision the stack.
3
3
  class Cloud
4
+ include Output
4
5
 
5
6
  # Initialize a Cloud instance
6
7
  #
@@ -334,6 +335,33 @@ module Cloudster
334
335
  return @cloud_formation.describe_stacks('StackName' => options[:stack_name]).body["Stacks"][0] rescue nil
335
336
  end
336
337
 
338
+ # Returns a hash containing the output values of each resource in the Stack
339
+ #
340
+ # ==== Examples
341
+ # cloud = Cloudster::Cloud.new(
342
+ # :access_key_id => 'aws_access_key_id',
343
+ # :secret_access_key => 'aws_secret_access_key',
344
+ # :region => 'us-east-1'
345
+ # )
346
+ # cloud.outputs(:stack_name => 'RDSStack')
347
+ #
348
+ # ==== Parameters
349
+ # * options<~Hash>
350
+ # * :stack_name : A string which will contain the name of the stack
351
+ #
352
+ # ==== Returns
353
+ # * Hash containing outputs of the stack
354
+ def outputs(options = {})
355
+ require_options(options, [:stack_name])
356
+ stack_description = describe(:stack_name => options[:stack_name])
357
+ outputs = stack_description["Outputs"] rescue nil
358
+ outputs_hash = {}
359
+ outputs.each do |output|
360
+ outputs_hash[output["OutputKey"]] = parse_outputs(output["OutputValue"])
361
+ end
362
+ return outputs_hash
363
+ end
364
+
337
365
  # Returns the status of the stack
338
366
  #
339
367
  # ==== Examples
@@ -7,11 +7,20 @@ module Cloudster
7
7
  def output_template(outputs)
8
8
  resource_name = outputs.keys[0]
9
9
  outputs_array = outputs.values[0].collect
10
- each_output_join = outputs_array.collect {|output| {"Fn::Join" => [":", output]}}
10
+ each_output_join = outputs_array.collect {|output| {"Fn::Join" => ["|", output]}}
11
11
  return resource_name => {
12
12
  'Value' => { "Fn::Join" => [ ",", each_output_join] }
13
13
  }
14
14
  end
15
15
 
16
+ def parse_outputs(output)
17
+ output_hash = {}
18
+ output.split(',').each do |attribute|
19
+ key_value = attribute.split('|')
20
+ output_hash[key_value[0]] = key_value[1]
21
+ end
22
+ return output_hash
23
+ end
24
+
16
25
  end
17
26
  end
@@ -40,9 +40,9 @@ describe Cloudster::ChefClient do
40
40
  "Value"=>{
41
41
  "Fn::Join"=>[",",
42
42
  [
43
- {"Fn::Join"=>[":", ["bucket_name", {"Ref"=>"S3ResourceName"}]]},
44
- {"Fn::Join"=>[":", ["dns_name", {"Fn::GetAtt"=>["S3ResourceName", "DomainName"]}]]},
45
- {"Fn::Join"=>[":", ["website_url", {"Fn::GetAtt"=>["S3ResourceName", "WebsiteURL"]}]]}
43
+ {"Fn::Join"=>["|", ["bucket_name", {"Ref"=>"S3ResourceName"}]]},
44
+ {"Fn::Join"=>["|", ["dns_name", {"Fn::GetAtt"=>["S3ResourceName", "DomainName"]}]]},
45
+ {"Fn::Join"=>["|", ["website_url", {"Fn::GetAtt"=>["S3ResourceName", "WebsiteURL"]}]]}
46
46
  ]
47
47
  ]
48
48
  }
@@ -127,6 +127,40 @@ describe Cloudster::Cloud do
127
127
  end
128
128
  end
129
129
 
130
+ describe '#outputs' do
131
+ it "should raise argument error if resources not provided" do
132
+ cloud = Cloudster::Cloud.new(:access_key_id => 'test', :secret_access_key => 'test')
133
+ expect { cloud.outputs() }.to raise_error(ArgumentError, 'Missing required argument: stack_name')
134
+ end
135
+ it "should trigger 'describe stack' request" do
136
+ cloud_formation = double('CloudFormation')
137
+ Fog::AWS::CloudFormation.should_receive(:new).with(:aws_access_key_id => 'test', :aws_secret_access_key => 'test', :region => nil).and_return cloud_formation
138
+ cloud = Cloudster::Cloud.new(:access_key_id => 'test', :secret_access_key => 'test')
139
+ cloud.should_receive(:describe).with(:stack_name => 'stack_name').and_return ({
140
+ "Outputs"=>[{
141
+ "OutputValue"=>"bucket_name|teststack3-testbucket1,dns_name|teststack3-testbucket1.s3.amazonaws.com,website_url|http://teststack3-testbucket1.s3-website-us-east-1.amazonaws.com",
142
+ "OutputKey"=>"TestBucket1"
143
+ },{
144
+ "OutputValue"=>"bucket_name|teststack3-testbucket2,dns_name|teststack3-testbucket2.s3.amazonaws.com,website_url|http://teststack3-testbucket2.s3-website-us-east-1.amazonaws.com",
145
+ "OutputKey"=>"TestBucket2"
146
+ }]
147
+ })
148
+ output_hash = cloud.outputs(:stack_name => 'stack_name')
149
+ output_hash.should == ({
150
+ "TestBucket1" => {
151
+ "bucket_name" => "teststack3-testbucket1",
152
+ "dns_name" => "teststack3-testbucket1.s3.amazonaws.com",
153
+ "website_url" => "http://teststack3-testbucket1.s3-website-us-east-1.amazonaws.com"
154
+ },
155
+ "TestBucket2" => {
156
+ "bucket_name" => "teststack3-testbucket2",
157
+ "dns_name" => "teststack3-testbucket2.s3.amazonaws.com",
158
+ "website_url" => "http://teststack3-testbucket2.s3-website-us-east-1.amazonaws.com"
159
+ }
160
+ })
161
+ end
162
+ end
163
+
130
164
  describe "#is_s3_bucket_name_available?" do
131
165
  it "should return true if bucket is available" do
132
166
  cloud = Cloudster::Cloud.new(:access_key_id => 'test', :secret_access_key => 'test')
@@ -1,6 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Cloudster::Output do
4
+ class Resource;end
5
+ Resource.extend(Cloudster::Output)
6
+
4
7
  describe "output_template" do
5
8
  it "should return the cloudformation template for the Outputs" do
6
9
  resource_name = "S3ResourceName"
@@ -16,12 +19,26 @@ describe Cloudster::Output do
16
19
  resource_name => {
17
20
  "Value" => {
18
21
  "Fn::Join" => [ ",",[
19
- {"Fn::Join" => [":", ['bucket_name', {"Ref" => resource_name } ] ]},
20
- {"Fn::Join" => [":", ['dns_name', {'Fn::GetAtt' => [resource_name, 'DomainName']} ] ]}
22
+ {"Fn::Join" => ["|", ['bucket_name', {"Ref" => resource_name } ] ]},
23
+ {"Fn::Join" => ["|", ['dns_name', {'Fn::GetAtt' => [resource_name, 'DomainName']} ] ]}
21
24
  ]]
22
25
  }
23
26
  }
24
27
  }
25
28
  end
26
29
  end
30
+
31
+ describe "parse_outputs" do
32
+ it "should return a hash of outputs" do
33
+ outputs = "bucket_name|teststack3-testbucket1,dns_name|teststack3-testbucket1.s3.amazonaws.com,website_url|http://teststack3-testbucket1.s3-website-us-east-1.amazonaws.com"
34
+ class Resource;end
35
+ Resource.extend(Cloudster::Output)
36
+ Resource.parse_outputs(outputs).should == {
37
+ "bucket_name" => "teststack3-testbucket1",
38
+ "dns_name" => "teststack3-testbucket1.s3.amazonaws.com",
39
+ "website_url" => "http://teststack3-testbucket1.s3-website-us-east-1.amazonaws.com"
40
+ }
41
+ end
42
+ end
43
+
27
44
  end
@@ -15,14 +15,14 @@ describe Cloudster::S3 do
15
15
  s3 = Cloudster::S3.new(:name => 'bucket_name')
16
16
  s3.template.should == {
17
17
  'Resources' => {'bucket_name' => {'Type' => 'AWS::S3::Bucket', 'Properties' => {}}},
18
- "Outputs" => {"bucket_name"=>{"Value"=>{"Fn::Join"=>[",", [{"Fn::Join"=>[":", ["bucket_name", {"Ref"=>"bucket_name"}]]}, {"Fn::Join"=>[":", ["dns_name", {"Fn::GetAtt"=>["bucket_name", "DomainName"]}]]}, {"Fn::Join"=>[":", ["website_url", {"Fn::GetAtt"=>["bucket_name", "WebsiteURL"]}]]}]]}}}
18
+ "Outputs" => {"bucket_name"=>{"Value"=>{"Fn::Join"=>[",", [{"Fn::Join"=>["|", ["bucket_name", {"Ref"=>"bucket_name"}]]}, {"Fn::Join"=>["|", ["dns_name", {"Fn::GetAtt"=>["bucket_name", "DomainName"]}]]}, {"Fn::Join"=>["|", ["website_url", {"Fn::GetAtt"=>["bucket_name", "WebsiteURL"]}]]}]]}}}
19
19
  }
20
20
  end
21
21
  it "should return a ruby hash for the resource cloudformation template" do
22
22
  s3 = Cloudster::S3.new(:name => 'bucket_name', :access_control => "PublicRead", :website_configuration => {"index_document" => "index.html", "error_document" => "error.html"} )
23
23
  s3.template.should == {
24
24
  'Resources' => {'bucket_name' => {'Type' => 'AWS::S3::Bucket', 'Properties' => {"AccessControl" => "PublicRead", "WebsiteConfiguration" => { "IndexDocument" => "index.html", "ErrorDocument" => "error.html" } }}},
25
- "Outputs" => {"bucket_name"=>{"Value"=>{"Fn::Join"=>[",", [{"Fn::Join"=>[":", ["bucket_name", {"Ref"=>"bucket_name"}]]}, {"Fn::Join"=>[":", ["dns_name", {"Fn::GetAtt"=>["bucket_name", "DomainName"]}]]}, {"Fn::Join"=>[":", ["website_url", {"Fn::GetAtt"=>["bucket_name", "WebsiteURL"]}]]}]]}}}
25
+ "Outputs" => {"bucket_name"=>{"Value"=>{"Fn::Join"=>[",", [{"Fn::Join"=>["|", ["bucket_name", {"Ref"=>"bucket_name"}]]}, {"Fn::Join"=>["|", ["dns_name", {"Fn::GetAtt"=>["bucket_name", "DomainName"]}]]}, {"Fn::Join"=>["|", ["website_url", {"Fn::GetAtt"=>["bucket_name", "WebsiteURL"]}]]}]]}}}
26
26
  }
27
27
  end
28
28
  end
@@ -35,7 +35,7 @@ describe Cloudster::S3 do
35
35
  hash = Cloudster::S3.template(:name => 'bucket_name', :access_control => "PublicRead", :website_configuration => {"index_document" => "index.html", "error_document" => "error.html"} )
36
36
  hash.should == {
37
37
  'Resources' => {'bucket_name' => {'Type' => 'AWS::S3::Bucket', 'Properties' => {"AccessControl" => "PublicRead", "WebsiteConfiguration" => { "IndexDocument" => "index.html", "ErrorDocument" => "error.html" } }}},
38
- "Outputs" => {"bucket_name"=>{"Value"=>{"Fn::Join"=>[",", [{"Fn::Join"=>[":", ["bucket_name", {"Ref"=>"bucket_name"}]]}, {"Fn::Join"=>[":", ["dns_name", {"Fn::GetAtt"=>["bucket_name", "DomainName"]}]]}, {"Fn::Join"=>[":", ["website_url", {"Fn::GetAtt"=>["bucket_name", "WebsiteURL"]}]]}]]}}}
38
+ "Outputs" => {"bucket_name"=>{"Value"=>{"Fn::Join"=>[",", [{"Fn::Join"=>["|", ["bucket_name", {"Ref"=>"bucket_name"}]]}, {"Fn::Join"=>["|", ["dns_name", {"Fn::GetAtt"=>["bucket_name", "DomainName"]}]]}, {"Fn::Join"=>["|", ["website_url", {"Fn::GetAtt"=>["bucket_name", "WebsiteURL"]}]]}]]}}}
39
39
  }
40
40
  end
41
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudster
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.18.0
4
+ version: 2.19.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-08 00:00:00.000000000 Z
12
+ date: 2013-01-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
@@ -169,7 +169,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
169
169
  version: '0'
170
170
  segments:
171
171
  - 0
172
- hash: 571049873
172
+ hash: 136420239
173
173
  required_rubygems_version: !ruby/object:Gem::Requirement
174
174
  none: false
175
175
  requirements: