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.
@@ -16,87 +16,95 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'attribute_struct'
19
+ require 'sparkle_formation'
20
20
 
21
- module SparkleAttribute
21
+ class SparkleFormation
22
+ module SparkleAttribute
22
23
 
23
- def _cf_join(*args)
24
- options = args.detect{|i| i.is_a?(Hash) && i[:options]} || {:options => {}}
25
- args.delete(options)
26
- unless(args.size == 1)
27
- args = [args]
24
+ def _cf_join(*args)
25
+ options = args.detect{|i| i.is_a?(Hash) && i[:options]} || {:options => {}}
26
+ args.delete(options)
27
+ unless(args.size == 1)
28
+ args = [args]
29
+ end
30
+ {'Fn::Join' => [options[:options][:delimiter] || '', *args]}
28
31
  end
29
- {'Fn::Join' => [options[:options][:delimiter] || '', *args]}
30
- end
31
32
 
32
- def _cf_ref(thing)
33
- thing = _process_key(thing, :force) if thing.is_a?(Symbol)
34
- {'Ref' => thing}
35
- end
36
- alias_method :_ref, :_cf_ref
37
-
38
- def _cf_map(thing, key, *suffix)
39
- suffix = suffix.map do |item|
40
- if(item.is_a?(Symbol))
41
- _process_key(item, :force)
42
- else
43
- item
33
+ def _cf_ref(thing)
34
+ thing = _process_key(thing, :force) if thing.is_a?(Symbol)
35
+ {'Ref' => thing}
36
+ end
37
+ alias_method :_ref, :_cf_ref
38
+
39
+ def _cf_map(thing, key, *suffix)
40
+ suffix = suffix.map do |item|
41
+ if(item.is_a?(Symbol))
42
+ _process_key(item, :force)
43
+ else
44
+ item
45
+ end
44
46
  end
47
+ thing = _process_key(thing, :force) if thing.is_a?(Symbol)
48
+ key = _process_key(key, :force) if key.is_a?(Symbol)
49
+ {'Fn::FindInMap' => [_process_key(thing), {'Ref' => _process_key(key)}, *suffix]}
45
50
  end
46
- thing = _process_key(thing, :force) if thing.is_a?(Symbol)
47
- key = _process_key(key, :force) if key.is_a?(Symbol)
48
- {'Fn::FindInMap' => [_process_key(thing), {'Ref' => _process_key(key)}, *suffix]}
49
- end
50
- alias_method :_cf_find_in_map, :_cf_map
51
-
52
- def _cf_attr(*args)
53
- args = args.map do |thing|
54
- if(thing.is_a?(Symbol))
55
- _process_key(thing, :force)
56
- else
57
- thing
51
+ alias_method :_cf_find_in_map, :_cf_map
52
+
53
+ def _cf_attr(*args)
54
+ args = args.map do |thing|
55
+ if(thing.is_a?(Symbol))
56
+ _process_key(thing, :force)
57
+ else
58
+ thing
59
+ end
60
+
58
61
  end
62
+ {'Fn::GetAtt' => args}
63
+ end
64
+ alias_method :_cf_get_att, :_cf_attr
59
65
 
66
+ def _cf_base64(arg)
67
+ {'Fn::Base64' => arg}
60
68
  end
61
- {'Fn::GetAtt' => args}
62
- end
63
- alias_method :_cf_get_att, :_cf_attr
64
69
 
65
- def _cf_base64(arg)
66
- {'Fn::Base64' => arg}
67
- end
70
+ def _cf_get_azs(region=nil)
71
+ region = case region
72
+ when Symbol
73
+ _cf_ref(region)
74
+ when NilClass
75
+ ''
76
+ else
77
+ region
78
+ end
79
+ {'Fn::GetAZs' => region}
80
+ end
68
81
 
69
- def _cf_get_azs(region=nil)
70
- region = case region
71
- when Symbol
72
- _cf_ref(region)
73
- when NilClass
74
- ''
75
- else
76
- region
77
- end
78
- {'Fn::GetAZs' => region}
79
- end
82
+ def _cf_select(index, item)
83
+ item = _cf_ref(item) if item.is_a?(Symbol)
84
+ {'Fn::Select' => [index.to_i.to_s, item]}
85
+ end
80
86
 
81
- def _cf_select(index, item)
82
- item = _cf_ref(item) if item.is_a?(Symbol)
83
- {'Fn::Select' => [index.to_i.to_s, item]}
84
- end
87
+ def rhel?
88
+ !!@platform[:rhel]
89
+ end
85
90
 
86
- def rhel?
87
- !!@platform[:rhel]
88
- end
91
+ def debian?
92
+ !!@platform[:debian]
93
+ end
89
94
 
90
- def debian?
91
- !!@platform[:debian]
92
- end
95
+ def _platform=(plat)
96
+ @platform || __hashish
97
+ @platform.clear
98
+ @platform[plat.to_sym] = true
99
+ end
93
100
 
94
- def _platform=(plat)
95
- @platform || __hashish
96
- @platform.clear
97
- @platform[plat.to_sym] = true
98
- end
101
+ def dynamic!(name, *args, &block)
102
+ SparkleFormation.insert(name, self, *args, &block)
103
+ end
99
104
 
100
- end
105
+ def registry!(name, *args)
106
+ SfnRegistry.insert(name, self, *args)
107
+ end
101
108
 
102
- AttributeStruct.send(:include, SparkleAttribute)
109
+ end
110
+ end
@@ -16,11 +16,9 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- require 'attribute_struct'
20
- require 'sparkle_formation/sparkle_attribute'
21
- require 'sparkle_formation/utils'
19
+ require 'sparkle_formation'
22
20
 
23
- AttributeStruct.camel_keys = true
21
+ SparkleFormation::SparkleStruct.camel_keys = true
24
22
 
25
23
  class SparkleFormation
26
24
 
@@ -28,38 +26,85 @@ class SparkleFormation
28
26
 
29
27
  class << self
30
28
 
29
+ include SparkleFormation::Utils::AnimalStrings
30
+
31
31
  attr_reader :dynamics
32
- attr_reader :components_path
33
- attr_reader :dynamics_path
34
32
 
33
+ # Return custom paths
35
34
  def custom_paths
36
35
  @_paths ||= {}
37
36
  @_paths
38
37
  end
39
38
 
40
- def components_path=(path)
41
- custom_paths[:sparkle_path] = path
39
+ # path:: Path
40
+ # Path to sparkle directory
41
+ def sparkle_path=(path=nil)
42
+ if(path)
43
+ custom_paths[:sparkle_path] = path
44
+ custom_paths[:components_directory] ||= File.join(path, 'components')
45
+ custom_paths[:dynamics_directory] ||= File.join(path, 'dynamics')
46
+ custom_paths[:registry_directory] ||= File.join(path, 'registry')
47
+ end
48
+ custom_paths[:sparkle_path]
49
+ end
50
+ alias_method(:sparkle_path, :sparkle_path=)
51
+
52
+ # path:: Path
53
+ # Set path to component files
54
+ def components_path=(path=nil)
55
+ if(path)
56
+ custom_paths[:components_directory] = path
57
+ end
58
+ custom_paths[:components_directory]
59
+ end
60
+ alias_method(:components_path, :components_path=)
61
+
62
+ # path:: Path
63
+ # Set path to dynamic files
64
+ def dynamics_path=(path=nil)
65
+ if(path)
66
+ custom_paths[:dynamics_directory] = path
67
+ end
68
+ custom_paths[:dynamics_directory]
42
69
  end
70
+ alias_method(:dynamics_path, :dynamics_path=)
43
71
 
44
- def dynamics_path=(path)
45
- custom_paths[:dynamics_directory] = path
72
+ # path:: Path
73
+ # Set path to registry files
74
+ def registry_path=(path=nil)
75
+ if(path)
76
+ custom_paths[:registry_directory] = path
77
+ end
78
+ custom_paths[:registry_directory]
46
79
  end
80
+ alias_method(:registry_path, :registry_path=)
47
81
 
82
+ # path:: Path
83
+ # args:: Option symbols
84
+ # - :sparkle:: Return formation instead of Hash
85
+ # Compile file at given path and return Hash
48
86
  def compile(path, *args)
49
87
  formation = self.instance_eval(IO.read(path), path, 1)
50
88
  args.include?(:sparkle) ? formation : formation.compile._dump
51
89
  end
52
90
 
91
+ # base:: Base SparkleStruct
92
+ # Execute given block within base
53
93
  def build(base=nil, &block)
54
- struct = base || AttributeStruct.new
94
+ struct = base || SparkleStruct.new
55
95
  struct.instance_exec(&block)
56
- struct
96
+ @_struct = struct
57
97
  end
58
98
 
99
+ # path:: Path
100
+ # Load component at given path
59
101
  def load_component(path)
60
102
  self.instance_eval(IO.read(path), path, 1)
103
+ @_struct
61
104
  end
62
105
 
106
+ # directory:: Path
107
+ # Load all dynamics within given directory
63
108
  def load_dynamics!(directory)
64
109
  @loaded_dynamics ||= []
65
110
  Dir.glob(File.join(directory, '*.rb')).each do |dyn|
@@ -72,22 +117,90 @@ class SparkleFormation
72
117
  true
73
118
  end
74
119
 
75
- def dynamic(name, &block)
76
- @dynamics ||= Mash.new
77
- @dynamics[name] = block
120
+ # directory:: Path
121
+ # Load all registry entries within given directory
122
+ def load_registry!(directory)
123
+ Dir.glob(File.join(directory, '*.rb')).each do |reg|
124
+ reg = File.expand_path(reg)
125
+ require reg
126
+ end
127
+ true
128
+ end
129
+
130
+ # name:: Name of dynamic
131
+ # args:: Optional dynamic metadata
132
+ # Define a new dynamic and store associated block
133
+ def dynamic(name, args={}, &block)
134
+ @dynamics ||= SparkleStruct.hashish.new
135
+ @dynamics[name] = SparkleStruct.hashish[
136
+ :block, block, :args, SparkleStruct.hashish[args.map(&:to_a)]
137
+ ]
138
+ end
139
+
140
+ # name:: Name of dynamic
141
+ # Return metadata about dynamic
142
+ def dynamic_info(name)
143
+ if(@dynamics[name])
144
+ @dynamics[name][:args]
145
+ else
146
+ raise KeyError.new("No dynamic registered with provided name (#{name})")
147
+ end
78
148
  end
149
+ alias_method :dynamic_information, :dynamic_info
79
150
 
80
- def insert(dynamic_name, struct, *args)
151
+ # dynamic_name:: Name of dynamic
152
+ # struct:: SparkleStruct instances
153
+ # args:: Args to pass to dynamic
154
+ # Inserts a dynamic into the given SparkleStruct instance
155
+ def insert(dynamic_name, struct, *args, &block)
156
+ result = false
81
157
  if(@dynamics && @dynamics[dynamic_name])
82
- struct.instance_exec(*args, &@dynamics[dynamic_name])
83
- struct
158
+ struct.instance_exec(*args, &@dynamics[dynamic_name][:block])
159
+ result = struct
84
160
  else
161
+ result = builtin_insert(dynamic_name, struct, *args, &block)
162
+ end
163
+ unless(result)
85
164
  raise "Failed to locate requested dynamic block for insertion: #{dynamic_name} (valid: #{@dynamics.keys.sort.join(', ')})"
86
165
  end
166
+ result
167
+ end
168
+
169
+ # dynamic_name:: Name of dynamic
170
+ # struct:: SparkleStruct instances
171
+ # args:: Args to pass to dynamic
172
+ # Inserts a builtin dynamic into the given SparkleStruct instance
173
+ def builtin_insert(dynamic_name, struct, *args, &block)
174
+ if(defined?(SfnAws) && lookup_key = SfnAws.registry_key(dynamic_name))
175
+ _name, _config = *args
176
+ _config ||= {}
177
+ return unless _name
178
+ new_resource = struct.resources.__send__("#{_name}_#{dynamic_name}".to_sym)
179
+ new_resource.type lookup_key
180
+ properties = new_resource.properties
181
+ SfnAws.resource(dynamic_name, :properties).each do |prop_name|
182
+ value = [prop_name, snake(prop_name)].map do |key|
183
+ _config[key] || _config[key.to_sym]
184
+ end.compact.first
185
+ if(value)
186
+ if(value.is_a?(Proc))
187
+ properties.__send__(prop_name).instance_exec(&value)
188
+ else
189
+ properties.__send__(prop_name, value)
190
+ end
191
+ end
192
+ end
193
+ new_resource.instance_exec(&block) if block
194
+ new_resource
195
+ end
87
196
  end
88
197
 
198
+ # hash:: Hash
199
+ # Attempts to load an SparkleStruct instance from and existing
200
+ # Hash instance
201
+ # NOTE: camel keys will do best effort at auto discovery
89
202
  def from_hash(hash)
90
- struct = AttributeStruct.new
203
+ struct = SparkleStruct.new
91
204
  struct._camel_keys_set(:auto_discovery)
92
205
  struct._load(hash)
93
206
  struct._camel_keys_set(nil)
@@ -97,6 +210,9 @@ class SparkleFormation
97
210
 
98
211
  attr_reader :name
99
212
  attr_reader :sparkle_path
213
+ attr_reader :components_directory
214
+ attr_reader :dynamics_directory
215
+ attr_reader :registry_directory
100
216
  attr_reader :components
101
217
  attr_reader :load_order
102
218
 
@@ -104,27 +220,43 @@ class SparkleFormation
104
220
  @name = name
105
221
  @sparkle_path = options[:sparkle_path] ||
106
222
  self.class.custom_paths[:sparkle_path] ||
107
- File.join(Dir.pwd, 'cloudformation/components')
223
+ File.join(Dir.pwd, 'cloudformation')
224
+ @components_directory = options[:components_directory] ||
225
+ self.class.custom_paths[:components_directory] ||
226
+ File.join(sparkle_path, 'components')
108
227
  @dynamics_directory = options[:dynamics_directory] ||
109
228
  self.class.custom_paths[:dynamics_directory] ||
110
- File.join(File.dirname(@sparkle_path), 'dynamics')
229
+ File.join(sparkle_path, 'dynamics')
230
+ @registry_directory = options[:registry_directory] ||
231
+ self.class.custom_paths[:registry_directory] ||
232
+ File.join(sparkle_path, 'registry')
111
233
  self.class.load_dynamics!(@dynamics_directory)
112
- @components = AttributeStruct.hashish.new
234
+ self.class.load_registry!(@registry_directory)
235
+ unless(options[:disable_aws_builtins])
236
+ require 'sparkle_formation/aws'
237
+ SfnAws.load!
238
+ end
239
+ @components = SparkleStruct.hashish.new
113
240
  @load_order = []
241
+ @overrides = []
114
242
  if(block)
115
243
  load_block(block)
116
244
  end
117
245
  end
118
246
 
247
+ # block:: block to execute
248
+ # Loads block
119
249
  def load_block(block)
120
250
  @components[:__base__] = self.class.build(&block)
121
251
  @load_order << :__base__
122
252
  end
123
253
 
254
+ # args:: symbols or paths for component loads
255
+ # Loads components into instance
124
256
  def load(*args)
125
257
  args.each do |thing|
126
258
  if(thing.is_a?(Symbol))
127
- path = File.join(sparkle_path, "#{thing}.rb")
259
+ path = File.join(components_directory, "#{thing}.rb")
128
260
  else
129
261
  path = thing
130
262
  end
@@ -135,19 +267,23 @@ class SparkleFormation
135
267
  self
136
268
  end
137
269
 
138
- def overrides(&block)
139
- @overrides = block
270
+ # Registers block into overrides
271
+ def overrides(args={}, &block)
272
+ @overrides << {:args => args, :block => block}
140
273
  self
141
274
  end
142
275
 
143
276
  # Returns compiled Mash instance
144
277
  def compile
145
- compiled = AttributeStruct.new
278
+ compiled = SparkleStruct.new
146
279
  @load_order.each do |key|
147
280
  compiled._merge!(components[key])
148
281
  end
149
- if(@overrides)
150
- self.class.build(compiled, &@overrides)
282
+ @overrides.each do |override|
283
+ if(override[:args] && !override[:args].empty?)
284
+ compiled._set_state(override[:args])
285
+ end
286
+ self.class.build(compiled, &override[:block])
151
287
  end
152
288
  compiled
153
289
  end