sparkle_formation 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +10 -0
- data/CONTRIBUTING.md +25 -0
- data/README.md +84 -76
- data/bin/aws_resources +36 -2
- data/examples/allinone/cloudformation/ec2_example.rb +1 -1
- data/examples/allinone/parse.rb +2 -0
- data/examples/ami_component/cloudformation/ec2_example.rb +13 -15
- data/examples/ami_component/parse.rb +2 -0
- data/lib/sparkle_formation.rb +1 -0
- data/lib/sparkle_formation/aws.rb +29 -14
- data/lib/sparkle_formation/sparkle_attribute.rb +64 -3
- data/lib/sparkle_formation/sparkle_formation.rb +133 -54
- data/lib/sparkle_formation/sparkle_struct.rb +3 -0
- data/lib/sparkle_formation/translation.rb +165 -39
- data/lib/sparkle_formation/translation/heat.rb +73 -8
- data/lib/sparkle_formation/translation/rackspace.rb +81 -10
- data/lib/sparkle_formation/utils.rb +37 -0
- data/lib/sparkle_formation/version.rb +1 -1
- data/sparkle_formation.gemspec +1 -1
- data/test/spec.rb +6 -0
- data/test/specs/attribute.rb +72 -0
- data/test/specs/basic.rb +76 -0
- data/test/specs/cloudformation/components/ami.rb +14 -0
- data/test/specs/cloudformation/dynamics/node.rb +16 -0
- data/test/specs/results/base.json +43 -0
- data/test/specs/results/base_with_map.json +50 -0
- data/test/specs/results/component.json +27 -0
- metadata +13 -5
- data/sparkle_formation-0.2.0.gem +0 -0
@@ -17,14 +17,24 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
class SparkleFormation
|
20
|
+
|
21
|
+
# Helper utilities
|
20
22
|
module Utils
|
21
23
|
|
24
|
+
# Animal stylings on strins
|
22
25
|
module AnimalStrings
|
23
26
|
|
27
|
+
# Camel case string
|
28
|
+
# @param string [String]
|
29
|
+
# @return [String]
|
24
30
|
def camel(string)
|
25
31
|
string.to_s.split('_').map{|k| "#{k.slice(0,1).upcase}#{k.slice(1,k.length)}"}.join
|
26
32
|
end
|
27
33
|
|
34
|
+
# Snake case (underscore) string
|
35
|
+
#
|
36
|
+
# @param string [String]
|
37
|
+
# @return [String]
|
28
38
|
def snake(string)
|
29
39
|
string.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').downcase.to_sym
|
30
40
|
end
|
@@ -33,19 +43,32 @@ class SparkleFormation
|
|
33
43
|
|
34
44
|
end
|
35
45
|
|
46
|
+
# Registry helper
|
36
47
|
class Registry
|
37
48
|
|
38
49
|
class << self
|
39
50
|
|
51
|
+
# Initialize registry
|
52
|
+
#
|
53
|
+
# @return [self]
|
40
54
|
def init!
|
41
55
|
@register = AttributeStruct.hashish.new
|
42
56
|
self
|
43
57
|
end
|
44
58
|
|
59
|
+
# Register block
|
60
|
+
#
|
61
|
+
# @param name [String, Symbol] name of item
|
62
|
+
# @yield block to register
|
45
63
|
def register(name, &block)
|
46
64
|
@register[name] = block
|
47
65
|
end
|
48
66
|
|
67
|
+
# Insert registry item into context
|
68
|
+
#
|
69
|
+
# @param name [String, Symbol] name of item
|
70
|
+
# @param location [AttributeStruct] context to apply block
|
71
|
+
# @param args [Object] argument list for block
|
49
72
|
def insert(name, location, *args)
|
50
73
|
if(block = @register[name])
|
51
74
|
location.instance_exec(*args, &block)
|
@@ -58,23 +81,37 @@ class SparkleFormation
|
|
58
81
|
|
59
82
|
end
|
60
83
|
|
84
|
+
# Cache helper
|
61
85
|
class Cache
|
62
86
|
class << self
|
63
87
|
|
88
|
+
# Get value
|
89
|
+
#
|
90
|
+
# @param k [Object]
|
91
|
+
# @return [Object]
|
64
92
|
def [](k)
|
65
93
|
init!
|
66
94
|
Thread.current[:sparkle_cache][k]
|
67
95
|
end
|
68
96
|
|
97
|
+
# Set value
|
98
|
+
#
|
99
|
+
# @param k [Object] key
|
100
|
+
# @param v [Object] value
|
101
|
+
# @return [Object] v
|
69
102
|
def []=(k,v)
|
70
103
|
init!
|
71
104
|
Thread.current[:sparkle_cache][k] = v
|
72
105
|
end
|
73
106
|
|
107
|
+
# Initialize cache within thread
|
108
|
+
#
|
109
|
+
# @return [self]
|
74
110
|
def init!
|
75
111
|
unless(Thread.current[:sparkle_cache])
|
76
112
|
Thread.current[:sparkle_cache] = {}
|
77
113
|
end
|
114
|
+
self
|
78
115
|
end
|
79
116
|
|
80
117
|
end
|
data/sparkle_formation.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.description = 'Cloud Formation builder'
|
11
11
|
s.license = 'Apache-2.0'
|
12
12
|
s.require_path = 'lib'
|
13
|
-
s.add_dependency 'attribute_struct', '~> 0.
|
13
|
+
s.add_dependency 'attribute_struct', '~> 0.2.2'
|
14
14
|
s.add_dependency 'multi_json'
|
15
15
|
s.files = Dir['**/*']
|
16
16
|
end
|
data/test/spec.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
describe SparkleFormation::SparkleAttribute do
|
2
|
+
|
3
|
+
before do
|
4
|
+
@attr = Object.new
|
5
|
+
@attr.extend(SparkleFormation::SparkleAttribute)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should generate Fn::Join' do
|
9
|
+
@attr.join!('a', 'b', 'c').must_equal 'Fn::Join' => ['', ['a', 'b', 'c']]
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should generate Fn::Join with custom delimiter' do
|
13
|
+
@attr.join!('a', 'b', 'c', :options => {:delimiter => '-'}).
|
14
|
+
must_equal 'Fn::Join' => ['-', ['a', 'b', 'c']]
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should generate Ref' do
|
18
|
+
@attr.ref!('Item').must_equal 'Ref' => 'Item'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should process symbol when generating Ref' do
|
22
|
+
SparkleFormation.new(:dummy) do
|
23
|
+
thing ref!(:item)
|
24
|
+
end.dump.must_equal 'Thing' => {'Ref' => 'Item'}
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should generate Fn::FindInMap' do
|
28
|
+
SparkleFormation.new(:dummy) do
|
29
|
+
thing find_in_map!('MyMap', 'MyKey', 'SubKey')
|
30
|
+
end.dump.
|
31
|
+
must_equal 'Thing' => {'Fn::FindInMap' => ['MyMap', {'Ref' => 'MyKey'}, 'SubKey']}
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should generate Fn::GetAtt' do
|
35
|
+
SparkleFormation.new(:dummy) do
|
36
|
+
thing attr!(:resource, 'my_instance', :ip_address)
|
37
|
+
end.dump.
|
38
|
+
must_equal 'Thing' => {'Fn::GetAtt' => ['Resource', 'my_instance', 'IpAddress']}
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should generate Fn::Base64' do
|
42
|
+
@attr.base64!('my string!').must_equal 'Fn::Base64' => 'my string!'
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should generate Fn::GetAZs' do
|
46
|
+
@attr.azs!.must_equal 'Fn::GetAZs' => ''
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should generate Fn::GetAZs with argument' do
|
50
|
+
@attr.azs!('fubar').must_equal 'Fn::GetAZs' => 'fubar'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should generate Fn::GetAZs with Ref when provided symbol' do
|
54
|
+
SparkleFormation.new(:dummy) do
|
55
|
+
thing azs!(:item)
|
56
|
+
end.dump.
|
57
|
+
must_equal 'Thing' => {'Fn::GetAZs' => {'Ref' => 'Item'}}
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should generate Fn::Select' do
|
61
|
+
@attr.select!(1, 'fubar').must_equal 'Fn::Select' => [1, 'fubar']
|
62
|
+
@attr.select!('1', 'fubar').must_equal 'Fn::Select' => ['1', 'fubar']
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should generate Fn::Select with Ref when provided symbol' do
|
66
|
+
SparkleFormation.new(:dummy) do
|
67
|
+
thing select!(:param, :fubar)
|
68
|
+
end.dump.
|
69
|
+
must_equal 'Thing' => {'Fn::Select' => [{'Ref' => 'Param'}, {'Ref' => 'Fubar'}]}
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/test/specs/basic.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
describe SparkleFormation do
|
2
|
+
|
3
|
+
before do
|
4
|
+
SparkleFormation.sparkle_path = File.join(
|
5
|
+
File.dirname(__FILE__), 'cloudformation'
|
6
|
+
)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'Basic Usage' do
|
10
|
+
|
11
|
+
it 'should dump hashes' do
|
12
|
+
SparkleFormation.new(:dummy) do
|
13
|
+
test true
|
14
|
+
end.dump.must_equal 'Test' => true
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should include components' do
|
18
|
+
SparkleFormation.new(:dummy).load(:ami).
|
19
|
+
dump.keys.must_include 'Mappings'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should process overrides' do
|
23
|
+
SparkleFormation.new(:dummy).overrides do
|
24
|
+
test true
|
25
|
+
end.dump.must_equal 'Test' => true
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should apply components on top of initial block' do
|
29
|
+
result = SparkleFormation.new(:dummy) do
|
30
|
+
mappings true
|
31
|
+
end.load(:ami).dump
|
32
|
+
result['Mappings'].must_be :is_a?, Hash
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should apply overrides on top of initial block and components' do
|
36
|
+
SparkleFormation.new(:dummy) do
|
37
|
+
mappings true
|
38
|
+
end.load(:ami).overrides do
|
39
|
+
mappings true
|
40
|
+
end.dump.must_equal 'Mappings' => true
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should should build component hash' do
|
44
|
+
component = MultiJson.load(File.read(File.join(File.dirname(__FILE__), 'results', 'component.json')))
|
45
|
+
SparkleFormation.new(:dummy).load(:ami).dump.must_equal component
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should build full stack' do
|
49
|
+
full_stack = MultiJson.load(File.read(File.join(File.dirname(__FILE__), 'results', 'base.json')))
|
50
|
+
SparkleFormation.new(:dummy).load(:ami).overrides do
|
51
|
+
dynamic!(:node, :my)
|
52
|
+
end.dump.must_equal full_stack
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should allow dynamic customization' do
|
56
|
+
full_stack = MultiJson.load(File.read(File.join(File.dirname(__FILE__), 'results', 'base_with_map.json')))
|
57
|
+
SparkleFormation.new(:dummy).load(:ami).overrides do
|
58
|
+
dynamic!(:node, :my) do
|
59
|
+
properties do
|
60
|
+
image_id map!(:region_map, 'AWS::Region', :ami)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end.dump.must_equal full_stack
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should allow customization of defined items' do
|
67
|
+
full_stack = MultiJson.load(File.read(File.join(File.dirname(__FILE__), 'results', 'base_with_map.json')))
|
68
|
+
SparkleFormation.new(:dummy).load(:ami).overrides do
|
69
|
+
dynamic!(:node, :my)
|
70
|
+
resources.my_ec2_instance.properties.image_id map!(:region_map, 'AWS::Region', :ami)
|
71
|
+
end.dump.must_equal full_stack
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
SparkleFormation.build do
|
2
|
+
|
3
|
+
mappings.region_map do
|
4
|
+
_set('us-east-1', :ami => 'ami-7f418316')
|
5
|
+
_set('us-east-1', :ami => 'ami-7f418316')
|
6
|
+
_set('us-west-1', :ami => 'ami-951945d0')
|
7
|
+
_set('us-west-2', :ami => 'ami-16fd7026')
|
8
|
+
_set('eu-west-1', :ami => 'ami-24506250')
|
9
|
+
_set('sa-east-1', :ami => 'ami-3e3be423')
|
10
|
+
_set('ap-southeast-1', :ami => 'ami-74dda626')
|
11
|
+
_set('ap-northeast-1', :ami => 'ami-dcfa4edd')
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
SparkleFormation.dynamic(:node) do |_name, _config|
|
2
|
+
|
3
|
+
parameters do
|
4
|
+
key_name do
|
5
|
+
description 'Name of an existing EC2 KeyPair to enable SSH access to the instance'
|
6
|
+
type 'String'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
dynamic!(:ec2_instance, _name) do
|
11
|
+
properties do
|
12
|
+
key_name ref!(:key_name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
{
|
2
|
+
"Parameters": {
|
3
|
+
"KeyName": {
|
4
|
+
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance",
|
5
|
+
"Type": "String"
|
6
|
+
}
|
7
|
+
},
|
8
|
+
"Mappings": {
|
9
|
+
"RegionMap": {
|
10
|
+
"Us-east-1": {
|
11
|
+
"Ami": "ami-7f418316"
|
12
|
+
},
|
13
|
+
"Us-west-1": {
|
14
|
+
"Ami": "ami-951945d0"
|
15
|
+
},
|
16
|
+
"Us-west-2": {
|
17
|
+
"Ami": "ami-16fd7026"
|
18
|
+
},
|
19
|
+
"Eu-west-1": {
|
20
|
+
"Ami": "ami-24506250"
|
21
|
+
},
|
22
|
+
"Sa-east-1": {
|
23
|
+
"Ami": "ami-3e3be423"
|
24
|
+
},
|
25
|
+
"Ap-southeast-1": {
|
26
|
+
"Ami": "ami-74dda626"
|
27
|
+
},
|
28
|
+
"Ap-northeast-1": {
|
29
|
+
"Ami": "ami-dcfa4edd"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
},
|
33
|
+
"Resources": {
|
34
|
+
"MyEc2Instance": {
|
35
|
+
"Type": "AWS::EC2::Instance",
|
36
|
+
"Properties": {
|
37
|
+
"KeyName": {
|
38
|
+
"Ref": "KeyName"
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
{
|
2
|
+
"Parameters": {
|
3
|
+
"KeyName": {
|
4
|
+
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance",
|
5
|
+
"Type": "String"
|
6
|
+
}
|
7
|
+
},
|
8
|
+
"Mappings": {
|
9
|
+
"RegionMap": {
|
10
|
+
"Us-east-1": {
|
11
|
+
"Ami": "ami-7f418316"
|
12
|
+
},
|
13
|
+
"Us-west-1": {
|
14
|
+
"Ami": "ami-951945d0"
|
15
|
+
},
|
16
|
+
"Us-west-2": {
|
17
|
+
"Ami": "ami-16fd7026"
|
18
|
+
},
|
19
|
+
"Eu-west-1": {
|
20
|
+
"Ami": "ami-24506250"
|
21
|
+
},
|
22
|
+
"Sa-east-1": {
|
23
|
+
"Ami": "ami-3e3be423"
|
24
|
+
},
|
25
|
+
"Ap-southeast-1": {
|
26
|
+
"Ami": "ami-74dda626"
|
27
|
+
},
|
28
|
+
"Ap-northeast-1": {
|
29
|
+
"Ami": "ami-dcfa4edd"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
},
|
33
|
+
"Resources": {
|
34
|
+
"MyEc2Instance": {
|
35
|
+
"Type": "AWS::EC2::Instance",
|
36
|
+
"Properties": {
|
37
|
+
"KeyName": {
|
38
|
+
"Ref": "KeyName"
|
39
|
+
},
|
40
|
+
"ImageId": {
|
41
|
+
"Fn::FindInMap": [
|
42
|
+
"RegionMap",
|
43
|
+
{"Ref": "AWS::Region"},
|
44
|
+
"Ami"
|
45
|
+
]
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
"Mappings": {
|
3
|
+
"RegionMap": {
|
4
|
+
"Us-east-1": {
|
5
|
+
"Ami": "ami-7f418316"
|
6
|
+
},
|
7
|
+
"Us-west-1": {
|
8
|
+
"Ami": "ami-951945d0"
|
9
|
+
},
|
10
|
+
"Us-west-2": {
|
11
|
+
"Ami": "ami-16fd7026"
|
12
|
+
},
|
13
|
+
"Eu-west-1": {
|
14
|
+
"Ami": "ami-24506250"
|
15
|
+
},
|
16
|
+
"Sa-east-1": {
|
17
|
+
"Ami": "ami-3e3be423"
|
18
|
+
},
|
19
|
+
"Ap-southeast-1": {
|
20
|
+
"Ami": "ami-74dda626"
|
21
|
+
},
|
22
|
+
"Ap-northeast-1": {
|
23
|
+
"Ami": "ami-dcfa4edd"
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparkle_formation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.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: 2014-
|
12
|
+
date: 2014-05-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: attribute_struct
|
@@ -18,7 +18,7 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.2.2
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
29
|
+
version: 0.2.2
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: multi_json
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -60,7 +60,14 @@ files:
|
|
60
60
|
- lib/sparkle_formation/translation.rb
|
61
61
|
- lib/sparkle_formation/utils.rb
|
62
62
|
- lib/sparkle_formation.rb
|
63
|
-
-
|
63
|
+
- test/spec.rb
|
64
|
+
- test/specs/attribute.rb
|
65
|
+
- test/specs/results/component.json
|
66
|
+
- test/specs/results/base.json
|
67
|
+
- test/specs/results/base_with_map.json
|
68
|
+
- test/specs/basic.rb
|
69
|
+
- test/specs/cloudformation/components/ami.rb
|
70
|
+
- test/specs/cloudformation/dynamics/node.rb
|
64
71
|
- examples/allinone/parse.rb
|
65
72
|
- examples/allinone/cloudformation/ec2_example.rb
|
66
73
|
- examples/ami_component/parse.rb
|
@@ -73,6 +80,7 @@ files:
|
|
73
80
|
- bin/heat_resources
|
74
81
|
- bin/aws_resources
|
75
82
|
- CHANGELOG.md
|
83
|
+
- CONTRIBUTING.md
|
76
84
|
- Gemfile.lock
|
77
85
|
homepage: http://github.com/heavywater/sparkle_formation
|
78
86
|
licenses:
|