cloudster 2.18.0 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
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: