sparkle_formation 0.1.4 → 0.1.6

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.
@@ -0,0 +1,11 @@
1
+ require 'sparkle_formation'
2
+
3
+ class SparkleFormation
4
+ class SparkleStruct < AttributeStruct
5
+ include ::SparkleFormation::SparkleAttribute
6
+
7
+ def _klass
8
+ ::SparkleFormation::SparkleStruct
9
+ end
10
+ end
11
+ end
@@ -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!
@@ -19,5 +19,5 @@
19
19
  class SparkleFormation
20
20
  class Version < Gem::Version
21
21
  end
22
- VERSION = Version.new('0.1.4')
22
+ VERSION = Version.new('0.1.6')
23
23
  end
Binary file
@@ -11,5 +11,6 @@ Gem::Specification.new do |s|
11
11
  s.license = 'Apache-2.0'
12
12
  s.require_path = 'lib'
13
13
  s.add_dependency 'attribute_struct', '~> 0.1.8'
14
+ s.add_dependency 'multi_json'
14
15
  s.files = Dir['**/*']
15
16
  end
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
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: 2013-12-10 00:00:00.000000000 Z
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