cloudster 2.17.0 → 2.18.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/VERSION CHANGED
@@ -1 +1 @@
1
- 2.17.0
1
+ 2.18.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cloudster"
8
- s.version = "2.17.0"
8
+ s.version = "2.18.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-07"
12
+ s.date = "2013-01-08"
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 = [
@@ -37,15 +37,18 @@ Gem::Specification.new do |s|
37
37
  "lib/cloudster/elasticache.rb",
38
38
  "lib/cloudster/elb.rb",
39
39
  "lib/cloudster/options_manager.rb",
40
+ "lib/cloudster/output.rb",
40
41
  "lib/cloudster/rds.rb",
41
42
  "lib/cloudster/s3.rb",
42
43
  "spec/chef_client_spec.rb",
43
44
  "spec/cloud_front_spec.rb",
44
45
  "spec/cloud_spec.rb",
46
+ "spec/deep_merge_spec.rb",
45
47
  "spec/ec2_spec.rb",
46
48
  "spec/elastic_ip_spec.rb",
47
49
  "spec/elasticache_spec.rb",
48
50
  "spec/elb_spec.rb",
51
+ "spec/output_spec.rb",
49
52
  "spec/rds_spec.rb",
50
53
  "spec/s3_spec.rb",
51
54
  "spec/spec_helper.rb"
@@ -2,6 +2,7 @@
2
2
  #This file requires all dependencies
3
3
  require 'json'
4
4
  require 'fog'
5
+ require 'cloudster/output'
5
6
  require 'cloudster/options_manager'
6
7
  require 'cloudster/deep_merge'
7
8
  include OptionsManager
@@ -59,14 +59,17 @@ module Cloudster
59
59
  resources = options[:resources]
60
60
  description = options[:description] || 'This stack is created by Cloudster'
61
61
  resource_template = {}
62
+ output_template = {}
62
63
  resources.each do |resource|
63
64
  resource_template.merge!(resource.template['Resources'])
65
+ output_template.merge!(resource.template['Outputs']) unless resource.template['Outputs'].nil?
64
66
  end
65
67
 
66
68
  cloud_template = {'AWSTemplateFormatVersion' => '2010-09-09',
67
- 'Description' => description,
68
- 'Resources' => resource_template
69
+ 'Description' => description
69
70
  }
71
+ cloud_template['Resources'] = resource_template if !resource_template.empty?
72
+ cloud_template['Outputs'] = output_template if !output_template.empty?
70
73
  return cloud_template.to_json
71
74
  end
72
75
 
@@ -257,7 +260,7 @@ module Cloudster
257
260
  ec2_resource_ids.each do |key, value|
258
261
  ec2_instance_details = ec2.describe_instances('instance-id' => value)
259
262
  ec2_details[key] = ec2_instance_details.body["reservationSet"][0]["instancesSet"][0] rescue nil
260
- end
263
+ end
261
264
  return ec2_details
262
265
  end
263
266
 
@@ -1,4 +1,4 @@
1
- # Stolen shamelessly from here http://apidock.com/rails/Hash/deep_merge!
1
+ # Stolen shamelessly from Rails : http://apidock.com/rails/Hash/deep_merge!
2
2
  class Hash
3
3
  def deep_merge(other_hash)
4
4
  other_hash.each_pair do |k,v|
@@ -6,4 +6,9 @@ module OptionsManager
6
6
  end
7
7
  raise ArgumentError, "Missing required argument: #{missing_args.join(',')}" unless missing_args.empty?
8
8
  end
9
+
10
+ def validate_option_in_list(option, list)
11
+ raise ArgumentError, "Option: #{option} should be one of #{list.inspect}" unless list.include?(option)
12
+ end
13
+
9
14
  end
@@ -0,0 +1,17 @@
1
+ module Cloudster
2
+ module Output
3
+ # Returns the Output template for resources
4
+ #
5
+ # ==== Parameters
6
+ # * output: Hash containing the valid outputs and their cloudformation translations
7
+ def output_template(outputs)
8
+ resource_name = outputs.keys[0]
9
+ outputs_array = outputs.values[0].collect
10
+ each_output_join = outputs_array.collect {|output| {"Fn::Join" => [":", output]}}
11
+ return resource_name => {
12
+ 'Value' => { "Fn::Join" => [ ",", each_output_join] }
13
+ }
14
+ end
15
+
16
+ end
17
+ end
@@ -1,6 +1,8 @@
1
1
  module Cloudster
2
2
  #S3 Resource
3
+ #Output values : bucket_name, dns_name, website_url
3
4
  class S3
5
+ extend Cloudster::Output
4
6
 
5
7
  attr_accessor :name, :template
6
8
  # Initialize a s3 bucket
@@ -38,7 +40,12 @@ module Cloudster
38
40
  # ==== Returns
39
41
  # * Ruby hash version of the Cloud Formation template for the s3 resource
40
42
  def template
41
- @template ||= S3.template({:name => @name, :access_control => @access_control, :website_configuration => @website_configuration})
43
+ @template ||= S3.template({
44
+ :name => @name,
45
+ :access_control => @access_control,
46
+ :website_configuration => @website_configuration,
47
+ :outputs => @outputs
48
+ })
42
49
  end
43
50
 
44
51
  # Class method that returns a Ruby hash version of the Cloud Formation template
@@ -63,13 +70,22 @@ module Cloudster
63
70
  unless options[:website_configuration].nil?
64
71
  properties.merge!({"WebsiteConfiguration" => {"IndexDocument" => options[:website_configuration]["index_document"], "ErrorDocument" => options[:website_configuration]["error_document"]}})
65
72
  end
66
- template = {'Resources' => {
67
- options[:name] => {
68
- 'Type' => 'AWS::S3::Bucket',
69
- 'Properties' => properties
70
- }
71
- }
73
+ outputs = {
74
+ options[:name] => {
75
+ 'bucket_name' => { 'Ref' => options[:name] },
76
+ 'dns_name' => {'Fn::GetAtt' => [options[:name], 'DomainName']},
77
+ 'website_url' => {'Fn::GetAtt' => [options[:name], 'WebsiteURL']}
78
+ }
72
79
  }
80
+ template = {
81
+ 'Resources' => {
82
+ options[:name] => {
83
+ 'Type' => 'AWS::S3::Bucket',
84
+ 'Properties' => properties
85
+ }
86
+ }
87
+ }
88
+ template['Outputs'] = output_template(outputs)
73
89
  return template
74
90
  end
75
91
  end
@@ -33,6 +33,19 @@ describe Cloudster::ChefClient do
33
33
  "Enabled"=>"true"
34
34
  }
35
35
  }
36
+ },
37
+ },
38
+ "Outputs" => {
39
+ "S3ResourceName"=>{
40
+ "Value"=>{
41
+ "Fn::Join"=>[",",
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"]}]]}
46
+ ]
47
+ ]
48
+ }
36
49
  }
37
50
  }
38
51
  }
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Hash" do
4
+ describe "#deep_merge" do
5
+ it "should do a deep merge for new keys and deep override for existing keys" do
6
+ hash1 = {
7
+ 'key1' => 'value1',
8
+ 'key2' => {
9
+ 'inner_key1' =>'inner_value1',
10
+ 'inner_key2' =>'inner_value2'
11
+ }
12
+ }
13
+ hash2 = {
14
+ 'key_to_merge' => 'value_to_merge',
15
+ 'key2' => {
16
+ 'inner_key_to_be_merged' =>'inner_value_to_be_merged',
17
+ 'inner_key2' =>'inner_value_to_override'
18
+ }
19
+ }
20
+ hash1.deep_merge(hash2).should == {
21
+ "key1"=>"value1",
22
+ "key2"=>{
23
+ "inner_key1"=>"inner_value1",
24
+ "inner_key2"=>"inner_value_to_override",
25
+ "inner_key_to_be_merged"=>"inner_value_to_be_merged"
26
+ },
27
+ "key_to_merge"=>"value_to_merge"
28
+ }
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cloudster::Output do
4
+ describe "output_template" do
5
+ it "should return the cloudformation template for the Outputs" do
6
+ resource_name = "S3ResourceName"
7
+ outputs = {
8
+ resource_name => {
9
+ 'bucket_name' => {"Ref" => resource_name },
10
+ 'dns_name' => {'Fn::GetAtt' => [resource_name, 'DomainName']}
11
+ }
12
+ }
13
+ class Resource;end
14
+ Resource.extend(Cloudster::Output)
15
+ Resource.output_template(outputs).should == {
16
+ resource_name => {
17
+ "Value" => {
18
+ "Fn::Join" => [ ",",[
19
+ {"Fn::Join" => [":", ['bucket_name', {"Ref" => resource_name } ] ]},
20
+ {"Fn::Join" => [":", ['dns_name', {'Fn::GetAtt' => [resource_name, 'DomainName']} ] ]}
21
+ ]]
22
+ }
23
+ }
24
+ }
25
+ end
26
+ end
27
+ end
@@ -13,11 +13,17 @@ describe Cloudster::S3 do
13
13
  describe '#template' do
14
14
  it "should return a ruby hash for the resource cloudformation template with only mandatory fields" do
15
15
  s3 = Cloudster::S3.new(:name => 'bucket_name')
16
- s3.template.should == {'Resources' => {'bucket_name' => {'Type' => 'AWS::S3::Bucket', 'Properties' => {}}}}
16
+ s3.template.should == {
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"]}]]}]]}}}
19
+ }
17
20
  end
18
21
  it "should return a ruby hash for the resource cloudformation template" do
19
22
  s3 = Cloudster::S3.new(:name => 'bucket_name', :access_control => "PublicRead", :website_configuration => {"index_document" => "index.html", "error_document" => "error.html"} )
20
- s3.template.should == {'Resources' => {'bucket_name' => {'Type' => 'AWS::S3::Bucket', 'Properties' => {"AccessControl" => "PublicRead", "WebsiteConfiguration" => { "IndexDocument" => "index.html", "ErrorDocument" => "error.html" } }}}}
23
+ s3.template.should == {
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"]}]]}]]}}}
26
+ }
21
27
  end
22
28
  end
23
29
 
@@ -27,7 +33,10 @@ describe Cloudster::S3 do
27
33
  end
28
34
  it "should return a ruby hash for the resource cloudformation template" do
29
35
  hash = Cloudster::S3.template(:name => 'bucket_name', :access_control => "PublicRead", :website_configuration => {"index_document" => "index.html", "error_document" => "error.html"} )
30
- hash.should == {'Resources' => {'bucket_name' => {'Type' => 'AWS::S3::Bucket', 'Properties' => {"AccessControl" => "PublicRead", "WebsiteConfiguration" => { "IndexDocument" => "index.html", "ErrorDocument" => "error.html" } }}}}
36
+ hash.should == {
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"]}]]}]]}}}
39
+ }
31
40
  end
32
41
  end
33
42
 
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.17.0
4
+ version: 2.18.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-07 00:00:00.000000000 Z
12
+ date: 2013-01-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fog
@@ -139,15 +139,18 @@ files:
139
139
  - lib/cloudster/elasticache.rb
140
140
  - lib/cloudster/elb.rb
141
141
  - lib/cloudster/options_manager.rb
142
+ - lib/cloudster/output.rb
142
143
  - lib/cloudster/rds.rb
143
144
  - lib/cloudster/s3.rb
144
145
  - spec/chef_client_spec.rb
145
146
  - spec/cloud_front_spec.rb
146
147
  - spec/cloud_spec.rb
148
+ - spec/deep_merge_spec.rb
147
149
  - spec/ec2_spec.rb
148
150
  - spec/elastic_ip_spec.rb
149
151
  - spec/elasticache_spec.rb
150
152
  - spec/elb_spec.rb
153
+ - spec/output_spec.rb
151
154
  - spec/rds_spec.rb
152
155
  - spec/s3_spec.rb
153
156
  - spec/spec_helper.rb
@@ -166,7 +169,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
166
169
  version: '0'
167
170
  segments:
168
171
  - 0
169
- hash: 500109
172
+ hash: 571049873
170
173
  required_rubygems_version: !ruby/object:Gem::Requirement
171
174
  none: false
172
175
  requirements: