sparkle_formation 0.1.4 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +7 -10
- data/bin/aws_resources +51 -0
- data/bin/heat_resources +33 -0
- data/lib/sparkle_formation.rb +11 -1
- data/lib/sparkle_formation/aws.rb +89 -0
- data/lib/sparkle_formation/aws/cfn_resources.rb +461 -0
- data/lib/sparkle_formation/sparkle_attribute.rb +75 -67
- data/lib/sparkle_formation/sparkle_formation.rb +164 -28
- data/lib/sparkle_formation/sparkle_struct.rb +11 -0
- data/lib/sparkle_formation/translation.rb +87 -0
- data/lib/sparkle_formation/translation/heat.rb +66 -0
- data/lib/sparkle_formation/translation/rackspace.rb +34 -0
- data/lib/sparkle_formation/utils.rb +50 -0
- data/lib/sparkle_formation/version.rb +1 -1
- data/sparkle_formation-0.2.0.gem +0 -0
- data/sparkle_formation.gemspec +1 -0
- metadata +27 -2
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'sparkle_formation'
|
2
|
+
require 'multi_json'
|
3
|
+
|
4
|
+
class SparkleFormation
|
5
|
+
class Translation
|
6
|
+
|
7
|
+
autoload :Heat, 'sparkle_formation/translation/heat'
|
8
|
+
autoload :Rackspace, 'sparkle_formation/translation/rackspace'
|
9
|
+
|
10
|
+
include SparkleFormation::Utils::AnimalStrings
|
11
|
+
include SparkleFormation::SparkleAttribute
|
12
|
+
|
13
|
+
attr_reader :original, :translated, :template, :logger
|
14
|
+
|
15
|
+
def initialize(template_hash, logger=nil)
|
16
|
+
@original = template_hash.dup
|
17
|
+
@template = MultiJson.load(MultiJson.dump(template_hash)) ## LOL: Lazy deep dup
|
18
|
+
@translated = {}
|
19
|
+
if(logger)
|
20
|
+
@logger = logger
|
21
|
+
else
|
22
|
+
require 'logger'
|
23
|
+
@logger = Logger.new($stdout)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def map
|
28
|
+
self.class.const_get(:MAP)
|
29
|
+
end
|
30
|
+
|
31
|
+
def translate!
|
32
|
+
template.each do |key, value|
|
33
|
+
translate_method = "translate_#{snake(key.to_s)}".to_sym
|
34
|
+
if(respond_to?(translate_method))
|
35
|
+
send(translate_method, value)
|
36
|
+
else
|
37
|
+
translate_default(key, value)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
def translate_default(key, value)
|
44
|
+
translated[key] = value
|
45
|
+
end
|
46
|
+
|
47
|
+
def translate_resources(value)
|
48
|
+
translated['Resources'] = {}.tap do |modified_resources|
|
49
|
+
value.each do |resource_name, resource_args|
|
50
|
+
new_resource = {}
|
51
|
+
lookup = map[:resources][resource_args['Type']]
|
52
|
+
unless(lookup)
|
53
|
+
logger.warn "Failed to locate resource type: #{resource_args['Type']}"
|
54
|
+
next
|
55
|
+
end
|
56
|
+
new_resource['Type'] = lookup[:name]
|
57
|
+
new_resource['Properties'] = {}.tap do |new_properties|
|
58
|
+
resource_args['Properties'].each do |property_name, property_value|
|
59
|
+
new_key = lookup[:properties][property_name]
|
60
|
+
if(new_key)
|
61
|
+
if(new_key.is_a?(Symbol))
|
62
|
+
new_key, new_value = send(new_key, property_value,
|
63
|
+
:new_resource => new_resource,
|
64
|
+
:new_properties => new_properties,
|
65
|
+
:original_resource => resource_args
|
66
|
+
)
|
67
|
+
new_properties[new_key] = new_value
|
68
|
+
else
|
69
|
+
new_properties[new_key] = property_value
|
70
|
+
end
|
71
|
+
else
|
72
|
+
logger.warn "Failed to locate property conversion for `#{property_name}` on resource type `#{resource_args['Type']}`. Passing directly."
|
73
|
+
new_properties[snake(property_name)] = property_value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
if(lookup[:finalizer])
|
78
|
+
send(lookup[:finalizer], resource_name, new_resource, resource_args, modified_resources)
|
79
|
+
end
|
80
|
+
resource_finalizer(resource_name, new_resource, resource_args, modified_resources)
|
81
|
+
modified_resources[resource_name] = new_resource
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
class SparkleFormation
|
2
|
+
class Translation
|
3
|
+
class Heat < Translation
|
4
|
+
|
5
|
+
# TODO: implement
|
6
|
+
def nova_server_block_device_mapping(value, args={})
|
7
|
+
['block_device_mapping', value]
|
8
|
+
end
|
9
|
+
|
10
|
+
def nova_server_user_data(value, args={})
|
11
|
+
args[:new_properties][:user_data_format] = 'RAW'
|
12
|
+
args[:new_properties][:config_drive] = 'true'
|
13
|
+
[:user_data, Hash[value.values.first]]
|
14
|
+
end
|
15
|
+
|
16
|
+
def nova_server_finalizer(*_)
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def resource_finalizer(resource_name, new_resource, old_resource, translated_resources)
|
21
|
+
%w(DependsOn Metadata).each do |key|
|
22
|
+
if(old_resource[key] && !new_resource[key])
|
23
|
+
new_resource[key] = old_resource[key]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO: implement
|
30
|
+
def autoscaling_group_resource(value, args={})
|
31
|
+
['resource', value]
|
32
|
+
end
|
33
|
+
|
34
|
+
MAP = {
|
35
|
+
:resources => {
|
36
|
+
'AWS::EC2::Instance' => {
|
37
|
+
:name => 'OS::Nova::Server',
|
38
|
+
:finalizer => :nova_server_finalizer,
|
39
|
+
:properties => {
|
40
|
+
'AvailabilityZone' => 'availability_zone',
|
41
|
+
'BlockDeviceMappings' => :nova_server_block_device_mapping,
|
42
|
+
'ImageId' => 'image',
|
43
|
+
'InstanceType' => 'flavor',
|
44
|
+
'KeyName' => 'key_name',
|
45
|
+
'NetworkInterfaces' => 'networks',
|
46
|
+
'SecurityGroups' => 'security_groups',
|
47
|
+
'SecurityGroupIds' => 'security_groups',
|
48
|
+
'Tags' => 'metadata',
|
49
|
+
'UserData' => :nova_server_user_data
|
50
|
+
}
|
51
|
+
},
|
52
|
+
'AWS::AutoScaling::AutoScalingGroup' => {
|
53
|
+
:name => 'OS::Heat::AutoScalingGroup',
|
54
|
+
:properties => {
|
55
|
+
'Cooldown' => 'cooldown',
|
56
|
+
'DesiredCapacity' => 'desired_capacity',
|
57
|
+
'MaxSize' => 'max_size',
|
58
|
+
'MinSize' => 'min_size',
|
59
|
+
'LaunchConfigurationName' => :autoscaling_group_resource
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class SparkleFormation
|
2
|
+
class Translation
|
3
|
+
class Rackspace < Heat
|
4
|
+
|
5
|
+
MAP = Heat::MAP
|
6
|
+
MAP[:resources]['AWS::EC2::Instance'][:name] = 'Rackspace::Cloud::Server'
|
7
|
+
|
8
|
+
def nova_server_finalizer(resource_name, new_resource, old_resource, translated_resources)
|
9
|
+
if(old_resource['Metadata'])
|
10
|
+
new_resource['Metadata'] = old_resource['Metadata']
|
11
|
+
if(new_resource['Metadata'] && new_resource['Metadata']['AWS::CloudFormation::Init'] && config = new_resource['Metadata']['AWS::CloudFormation::Init']['config'])
|
12
|
+
# NOTE: This is a stupid hack since HOT gives the URL to
|
13
|
+
# wget directly and if special characters exist, it fails
|
14
|
+
if(files = config['files'])
|
15
|
+
files.each do |key, args|
|
16
|
+
if(args['source'])
|
17
|
+
args['source'].replace("\"#{args['source']}\"")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def nova_server_user_data(value, args={})
|
26
|
+
result = super
|
27
|
+
args[:new_properties].delete(:user_data_format)
|
28
|
+
args[:new_properties].delete(:config_drive)
|
29
|
+
result
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -32,4 +32,54 @@ class SparkleFormation
|
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
35
|
+
|
36
|
+
class Registry
|
37
|
+
|
38
|
+
class << self
|
39
|
+
|
40
|
+
def init!
|
41
|
+
@register = AttributeStruct.hashish.new
|
42
|
+
self
|
43
|
+
end
|
44
|
+
|
45
|
+
def register(name, &block)
|
46
|
+
@register[name] = block
|
47
|
+
end
|
48
|
+
|
49
|
+
def insert(name, location, *args)
|
50
|
+
if(block = @register[name])
|
51
|
+
location.instance_exec(*args, &block)
|
52
|
+
else
|
53
|
+
raise KeyError.new("Requested item not found in registry (#{name})")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
class Cache
|
62
|
+
class << self
|
63
|
+
|
64
|
+
def [](k)
|
65
|
+
init!
|
66
|
+
Thread.current[:sparkle_cache][k]
|
67
|
+
end
|
68
|
+
|
69
|
+
def []=(k,v)
|
70
|
+
init!
|
71
|
+
Thread.current[:sparkle_cache][k] = v
|
72
|
+
end
|
73
|
+
|
74
|
+
def init!
|
75
|
+
unless(Thread.current[:sparkle_cache])
|
76
|
+
Thread.current[:sparkle_cache] = {}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
35
82
|
end
|
83
|
+
|
84
|
+
SfnCache = SparkleFormation::Cache
|
85
|
+
SfnRegistry = SparkleFormation::Registry.init!
|
Binary file
|
data/sparkle_formation.gemspec
CHANGED
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.1.
|
4
|
+
version: 0.1.6
|
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:
|
12
|
+
date: 2014-06-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: attribute_struct
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 0.1.8
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: multi_json
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
30
46
|
description: Cloud Formation builder
|
31
47
|
email: chrisroberts.code@gmail.com
|
32
48
|
executables: []
|
@@ -34,10 +50,17 @@ extensions: []
|
|
34
50
|
extra_rdoc_files: []
|
35
51
|
files:
|
36
52
|
- lib/sparkle_formation/sparkle_attribute.rb
|
53
|
+
- lib/sparkle_formation/aws.rb
|
37
54
|
- lib/sparkle_formation/version.rb
|
55
|
+
- lib/sparkle_formation/aws/cfn_resources.rb
|
38
56
|
- lib/sparkle_formation/sparkle_formation.rb
|
57
|
+
- lib/sparkle_formation/sparkle_struct.rb
|
58
|
+
- lib/sparkle_formation/translation/rackspace.rb
|
59
|
+
- lib/sparkle_formation/translation/heat.rb
|
60
|
+
- lib/sparkle_formation/translation.rb
|
39
61
|
- lib/sparkle_formation/utils.rb
|
40
62
|
- lib/sparkle_formation.rb
|
63
|
+
- sparkle_formation-0.2.0.gem
|
41
64
|
- examples/allinone/parse.rb
|
42
65
|
- examples/allinone/cloudformation/ec2_example.rb
|
43
66
|
- examples/ami_component/parse.rb
|
@@ -47,6 +70,8 @@ files:
|
|
47
70
|
- sparkle_formation.gemspec
|
48
71
|
- README.md
|
49
72
|
- LICENSE
|
73
|
+
- bin/heat_resources
|
74
|
+
- bin/aws_resources
|
50
75
|
- CHANGELOG.md
|
51
76
|
- Gemfile.lock
|
52
77
|
homepage: http://github.com/heavywater/sparkle_formation
|