sparkle_formation 0.1.6 → 0.2.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.
@@ -1,24 +1,31 @@
1
1
  require 'sparkle_formation'
2
2
 
3
3
  class SparkleFormation
4
+ # AWS resource helper
4
5
  class Aws
5
6
  class << self
6
7
 
7
8
  include SparkleFormation::Utils::AnimalStrings
9
+ # @!parse include SparkleFormation::Utils::AnimalStrings
8
10
 
9
- # type:: AWS CFN resource type
10
- # hash:: Hash of information
11
11
  # Register an AWS resource
12
+ #
13
+ # @param type [String] AWS CFN resource type
14
+ # @param hash [Hash] metadata information
15
+ # @return [TrueClass]
12
16
  def register(type, hash)
13
17
  unless(class_variable_defined?(:@@registry))
14
18
  @@registry = AttributeStruct.hashish.new
15
19
  end
16
20
  @@registry[type] = hash
21
+ true
17
22
  end
18
23
 
19
- # identifier:: resource identifier
20
- # key:: key of value to return from information hash
21
- # Return the associated aws resource information
24
+ # Resource information
25
+ #
26
+ # @param identifier [String, Symbol] resource identifier
27
+ # @param key [String, Symbol] specific data
28
+ # @return [Hashish]
22
29
  def resource(identifier, key=nil)
23
30
  res = lookup(identifier)
24
31
  if(key && res)
@@ -28,8 +35,10 @@ class SparkleFormation
28
35
  end
29
36
  end
30
37
 
31
- # json_path_or_hash:: Path to JSON file or Hash instance of resources
32
38
  # Register all discovered resources
39
+ #
40
+ # @param json_path_or_hash [String, Hashish] path to files or hash
41
+ # @return [TrueClass]
33
42
  def load(json_path_or_hash)
34
43
  if(json_path_or_hash.is_a?(String))
35
44
  require 'json'
@@ -44,14 +53,18 @@ class SparkleFormation
44
53
  end
45
54
 
46
55
  # Load the builtin AWS resources
56
+ #
57
+ # @return [TrueClass]
47
58
  def load!
48
59
  require File.join(File.dirname(__FILE__), 'aws', 'cfn_resources.rb')
49
60
  load(AWS_RESOURCES)
61
+ true
50
62
  end
51
63
 
52
- # key:: string or symbol
53
- # Return matching registry key. Uses snaked resource type for
54
- # matching and will attempt all parts for match
64
+ # Discover registry key via part searching
65
+ #
66
+ # @param key [String, Symbol]
67
+ # @return [String, NilClass]
55
68
  def registry_key(key)
56
69
  key = key.to_s
57
70
  @@registry.keys.detect do |ref|
@@ -66,19 +79,20 @@ class SparkleFormation
66
79
  end
67
80
  end
68
81
 
69
- # key:: string or symbol
70
- # Returns resource information of type discovered via matching
71
- # using #registry_key
82
+ # Registry information for given type
83
+ #
84
+ # @param key [String, Symbol]
85
+ # @return [Hashish, NilClass]
72
86
  def lookup(key)
73
87
  @@registry[registry_key(key)]
74
88
  end
75
89
 
76
- # Return the currently loaded AWS registry
90
+ # @return [Hashish] currently loaded AWS registry
77
91
  def registry
78
92
  if(class_variable_defined?(:@@registry))
79
93
  @@registry
80
94
  else
81
- {}
95
+ @@registry = AttributeStruct.hashish.new
82
96
  end
83
97
  end
84
98
 
@@ -86,4 +100,5 @@ class SparkleFormation
86
100
  end
87
101
  end
88
102
 
103
+ # Shortcut helper constant
89
104
  SfnAws = SparkleFormation::Aws
@@ -19,8 +19,14 @@
19
19
  require 'sparkle_formation'
20
20
 
21
21
  class SparkleFormation
22
+
23
+ # Provides template helper methods
22
24
  module SparkleAttribute
23
25
 
26
+ # Fn::Join generator
27
+ #
28
+ # @param args [Object]
29
+ # @return [Hash]
24
30
  def _cf_join(*args)
25
31
  options = args.detect{|i| i.is_a?(Hash) && i[:options]} || {:options => {}}
26
32
  args.delete(options)
@@ -29,13 +35,26 @@ class SparkleFormation
29
35
  end
30
36
  {'Fn::Join' => [options[:options][:delimiter] || '', *args]}
31
37
  end
38
+ alias_method :join!, :_cf_join
32
39
 
40
+ # Ref generator
41
+ #
42
+ # @param thing [String, Symbol] reference name
43
+ # @return [Hash]
44
+ # @note Symbol value will force key processing
33
45
  def _cf_ref(thing)
34
46
  thing = _process_key(thing, :force) if thing.is_a?(Symbol)
35
47
  {'Ref' => thing}
36
48
  end
37
49
  alias_method :_ref, :_cf_ref
38
-
50
+ alias_method :ref!, :_cf_ref
51
+
52
+ # Fn::FindInMap generator
53
+ #
54
+ # @param thing [String, Symbol] thing to find
55
+ # @param key [String, Symbol] thing to search
56
+ # @param suffix [Object] additional args
57
+ # @return [Hash]
39
58
  def _cf_map(thing, key, *suffix)
40
59
  suffix = suffix.map do |item|
41
60
  if(item.is_a?(Symbol))
@@ -49,7 +68,13 @@ class SparkleFormation
49
68
  {'Fn::FindInMap' => [_process_key(thing), {'Ref' => _process_key(key)}, *suffix]}
50
69
  end
51
70
  alias_method :_cf_find_in_map, :_cf_map
71
+ alias_method :find_in_map!, :_cf_map
72
+ alias_method :map!, :_cf_map
52
73
 
74
+ # Fn::GetAtt generator
75
+ #
76
+ # @param [Object] pass through arguments
77
+ # @return [Hash]
53
78
  def _cf_attr(*args)
54
79
  args = args.map do |thing|
55
80
  if(thing.is_a?(Symbol))
@@ -62,11 +87,22 @@ class SparkleFormation
62
87
  {'Fn::GetAtt' => args}
63
88
  end
64
89
  alias_method :_cf_get_att, :_cf_attr
90
+ alias_method :get_att!, :_cf_attr
91
+ alias_method :attr!, :_cf_attr
65
92
 
93
+ # Fn::Base64 generator
94
+ #
95
+ # @param arg [Object] pass through
96
+ # @return [Hash]
66
97
  def _cf_base64(arg)
67
98
  {'Fn::Base64' => arg}
68
99
  end
100
+ alias_method :base64!, :_cf_base64
69
101
 
102
+ # Fn::GetAZs generator
103
+ #
104
+ # @param region [String, Symbol] String will pass through. Symbol will be converted to ref
105
+ # @return [Hash]
70
106
  def _cf_get_azs(region=nil)
71
107
  region = case region
72
108
  when Symbol
@@ -78,30 +114,55 @@ class SparkleFormation
78
114
  end
79
115
  {'Fn::GetAZs' => region}
80
116
  end
81
-
117
+ alias_method :get_azs!, :_cf_get_azs
118
+ alias_method :azs!, :_cf_get_azs
119
+
120
+ # Fn::Select generator
121
+ #
122
+ # @param index [String, Symbol, Integer] Symbol will be converted to ref
123
+ # @param item [Object, Symbol] Symbol will be converted to ref
124
+ # @return [Hash]
82
125
  def _cf_select(index, item)
126
+ index = index.is_a?(Symbol) ? _cf_ref(index) : index
83
127
  item = _cf_ref(item) if item.is_a?(Symbol)
84
- {'Fn::Select' => [index.to_i.to_s, item]}
128
+ {'Fn::Select' => [index, item]}
85
129
  end
130
+ alias_method :select!, :_cf_select
86
131
 
132
+ # @return [TrueClass, FalseClass]
87
133
  def rhel?
88
134
  !!@platform[:rhel]
89
135
  end
90
136
 
137
+ # @return [TrueClass, FalseClass]
91
138
  def debian?
92
139
  !!@platform[:debian]
93
140
  end
94
141
 
142
+ # Set the destination platform
143
+ #
144
+ # @param plat [String, Symbol] one of :rhel or :debian
145
+ # @return [TrueClass]
95
146
  def _platform=(plat)
96
147
  @platform || __hashish
97
148
  @platform.clear
98
149
  @platform[plat.to_sym] = true
99
150
  end
100
151
 
152
+ # Dynamic insertion helper method
153
+ #
154
+ # @param name [String, Symbol] dynamic name
155
+ # @param args [Object] argument list for dynamic
156
+ # @return [self]
101
157
  def dynamic!(name, *args, &block)
102
158
  SparkleFormation.insert(name, self, *args, &block)
103
159
  end
104
160
 
161
+ # Registry insertion helper method
162
+ #
163
+ # @param name [String, Symbol] name of registry item
164
+ # @param args [Object] argument list for registry
165
+ # @return [self]
105
166
  def registry!(name, *args)
106
167
  SfnRegistry.insert(name, self, *args)
107
168
  end
@@ -20,24 +20,31 @@ require 'sparkle_formation'
20
20
 
21
21
  SparkleFormation::SparkleStruct.camel_keys = true
22
22
 
23
+ # Formation container
23
24
  class SparkleFormation
24
25
 
25
26
  include SparkleFormation::Utils::AnimalStrings
27
+ # @!parse include SparkleFormation::Utils::AnimalStrings
28
+ extend SparkleFormation::Utils::AnimalStrings
29
+ # @!parse extend SparkleFormation::Utils::AnimalStrings
26
30
 
27
31
  class << self
28
32
 
29
- include SparkleFormation::Utils::AnimalStrings
30
-
31
- attr_reader :dynamics
33
+ # @return [Hashish] loaded dynamics
34
+ def dynamics
35
+ @dynamics ||= SparkleStruct.hashish.new
36
+ end
32
37
 
33
- # Return custom paths
38
+ # @return [Hashish] custom paths
34
39
  def custom_paths
35
- @_paths ||= {}
40
+ @_paths ||= SparkleStruct.hashish.new
36
41
  @_paths
37
42
  end
38
43
 
39
- # path:: Path
40
- # Path to sparkle directory
44
+ # Get/set path to sparkle directory
45
+ #
46
+ # @param path [String] path to directory
47
+ # @return [String] path to directory
41
48
  def sparkle_path=(path=nil)
42
49
  if(path)
43
50
  custom_paths[:sparkle_path] = path
@@ -49,8 +56,10 @@ class SparkleFormation
49
56
  end
50
57
  alias_method(:sparkle_path, :sparkle_path=)
51
58
 
52
- # path:: Path
53
- # Set path to component files
59
+ # Get/set path to component files
60
+ #
61
+ # @param path [String] path to component files
62
+ # @return [String] path to component files
54
63
  def components_path=(path=nil)
55
64
  if(path)
56
65
  custom_paths[:components_directory] = path
@@ -59,8 +68,10 @@ class SparkleFormation
59
68
  end
60
69
  alias_method(:components_path, :components_path=)
61
70
 
62
- # path:: Path
63
- # Set path to dynamic files
71
+ # Get/set path to dynamic files
72
+ #
73
+ # @param path [String] path to dynamic files
74
+ # @return [String] path to dynamic files
64
75
  def dynamics_path=(path=nil)
65
76
  if(path)
66
77
  custom_paths[:dynamics_directory] = path
@@ -69,8 +80,10 @@ class SparkleFormation
69
80
  end
70
81
  alias_method(:dynamics_path, :dynamics_path=)
71
82
 
72
- # path:: Path
73
- # Set path to registry files
83
+ # Get/set path to registry files
84
+ #
85
+ # @param path [String] path to registry files
86
+ # @return [String] path to registry files
74
87
  def registry_path=(path=nil)
75
88
  if(path)
76
89
  custom_paths[:registry_directory] = path
@@ -79,32 +92,40 @@ class SparkleFormation
79
92
  end
80
93
  alias_method(:registry_path, :registry_path=)
81
94
 
82
- # path:: Path
83
- # args:: Option symbols
84
- # - :sparkle:: Return formation instead of Hash
85
- # Compile file at given path and return Hash
95
+ # Compile file
96
+ #
97
+ # @param path [String] path to file
98
+ # @param args [Object] use :sparkle to return struct
99
+ # @return [Hashish, SparkleStruct]
86
100
  def compile(path, *args)
87
101
  formation = self.instance_eval(IO.read(path), path, 1)
88
102
  args.include?(:sparkle) ? formation : formation.compile._dump
89
103
  end
90
104
 
91
- # base:: Base SparkleStruct
92
- # Execute given block within base
105
+ # Execute given block within struct context
106
+ #
107
+ # @param base [SparkleStruct] context for block
108
+ # @yield block to execute
109
+ # @return [SparkleStruct] provided base or new struct
93
110
  def build(base=nil, &block)
94
111
  struct = base || SparkleStruct.new
95
112
  struct.instance_exec(&block)
96
113
  @_struct = struct
97
114
  end
98
115
 
99
- # path:: Path
100
- # Load component at given path
116
+ # Load component
117
+ #
118
+ # @param path [String] path to component
119
+ # @return [SparkleStruct] resulting struct
101
120
  def load_component(path)
102
121
  self.instance_eval(IO.read(path), path, 1)
103
122
  @_struct
104
123
  end
105
124
 
106
- # directory:: Path
107
- # Load all dynamics within given directory
125
+ # Load all dynamics within a directory
126
+ #
127
+ # @param directory [String]
128
+ # @return [TrueClass]
108
129
  def load_dynamics!(directory)
109
130
  @loaded_dynamics ||= []
110
131
  Dir.glob(File.join(directory, '*.rb')).each do |dyn|
@@ -117,8 +138,10 @@ class SparkleFormation
117
138
  true
118
139
  end
119
140
 
120
- # directory:: Path
121
- # Load all registry entries within given directory
141
+ # Load all registry entries within a directory
142
+ #
143
+ # @param directory [String]
144
+ # @return [TrueClass]
122
145
  def load_registry!(directory)
123
146
  Dir.glob(File.join(directory, '*.rb')).each do |reg|
124
147
  reg = File.expand_path(reg)
@@ -127,49 +150,66 @@ class SparkleFormation
127
150
  true
128
151
  end
129
152
 
130
- # name:: Name of dynamic
131
- # args:: Optional dynamic metadata
132
- # Define a new dynamic and store associated block
153
+ # Define and register new dynamic
154
+ #
155
+ # @param name [String, Symbol] name of dynamic
156
+ # @param args [Hash] dynamic metadata
157
+ # @param args [Hash] :parameters description of _config parameters
158
+ # @example
159
+ # metadata describes dynamic parameters for _config hash:
160
+ # :item_name => {:description => 'Defines item name', :type => 'String'}
161
+ # @yield dynamic block
162
+ # @return [TrueClass]
133
163
  def dynamic(name, args={}, &block)
134
164
  @dynamics ||= SparkleStruct.hashish.new
135
- @dynamics[name] = SparkleStruct.hashish[
165
+ dynamics[name] = SparkleStruct.hashish[
136
166
  :block, block, :args, SparkleStruct.hashish[args.map(&:to_a)]
137
167
  ]
168
+ true
138
169
  end
139
170
 
140
- # name:: Name of dynamic
141
- # Return metadata about dynamic
171
+ # Metadata for dynamic
172
+ #
173
+ # @param name [String, Symbol] dynamic name
174
+ # @return [Hashish] metadata information
142
175
  def dynamic_info(name)
143
- if(@dynamics[name])
144
- @dynamics[name][:args]
176
+ if(dynamics[name])
177
+ dynamics[name][:args] ||= SparkleStruct.hashish.new
145
178
  else
146
179
  raise KeyError.new("No dynamic registered with provided name (#{name})")
147
180
  end
148
181
  end
149
182
  alias_method :dynamic_information, :dynamic_info
150
183
 
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
184
+ # Insert a dynamic into a context
185
+ #
186
+ # @param dynamic_name [String, Symbol] dynamic name
187
+ # @param struct [SparkleStruct] context for insertion
188
+ # @param args [Object] parameters for dynamic
189
+ # @return [SparkleStruct]
155
190
  def insert(dynamic_name, struct, *args, &block)
156
191
  result = false
157
192
  if(@dynamics && @dynamics[dynamic_name])
158
- struct.instance_exec(*args, &@dynamics[dynamic_name][:block])
193
+ result = struct.instance_exec(*args, &@dynamics[dynamic_name][:block])
194
+ if(block_given?)
195
+ result.instance_exec(&block)
196
+ end
159
197
  result = struct
160
198
  else
161
199
  result = builtin_insert(dynamic_name, struct, *args, &block)
162
200
  end
163
201
  unless(result)
164
- raise "Failed to locate requested dynamic block for insertion: #{dynamic_name} (valid: #{@dynamics.keys.sort.join(', ')})"
202
+ raise "Failed to locate requested dynamic block for insertion: #{dynamic_name} (valid: #{(@dynamics || {}).keys.sort.join(', ')})"
165
203
  end
166
204
  result
167
205
  end
168
206
 
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
207
+ # Insert a builtin dynamic into a context
208
+ #
209
+ # @param dynamic_name [String, Symbol] dynamic name
210
+ # @param struct [SparkleStruct] context for insertion
211
+ # @param args [Object] parameters for dynamic
212
+ # @return [SparkleStruct]
173
213
  def builtin_insert(dynamic_name, struct, *args, &block)
174
214
  if(defined?(SfnAws) && lookup_key = SfnAws.registry_key(dynamic_name))
175
215
  _name, _config = *args
@@ -195,10 +235,11 @@ class SparkleFormation
195
235
  end
196
236
  end
197
237
 
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
238
+ # Convert hash to SparkleStruct instance
239
+ #
240
+ # @param hash [Hashish]
241
+ # @return [SparkleStruct]
242
+ # @note will do best effort on camel key auto discovery
202
243
  def from_hash(hash)
203
244
  struct = SparkleStruct.new
204
245
  struct._camel_keys_set(:auto_discovery)
@@ -208,16 +249,33 @@ class SparkleFormation
208
249
  end
209
250
  end
210
251
 
252
+ # @return [Symbol] name of formation
211
253
  attr_reader :name
254
+ # @return [String] base path
212
255
  attr_reader :sparkle_path
256
+ # @return [String] components path
213
257
  attr_reader :components_directory
258
+ # @return [String] dynamics path
214
259
  attr_reader :dynamics_directory
260
+ # @return [String] registry path
215
261
  attr_reader :registry_directory
262
+ # @return [Array] components to load
216
263
  attr_reader :components
264
+ # @return [Array] order of loading
217
265
  attr_reader :load_order
218
266
 
267
+ # Create new instance
268
+ #
269
+ # @param name [String, Symbol] name of formation
270
+ # @param options [Hash] options
271
+ # @option options [String] :sparkle_path custom base path
272
+ # @option options [String] :components_directory custom components path
273
+ # @option options [String] :dynamics_directory custom dynamics path
274
+ # @option options [String] :registry_directory custom registry path
275
+ # @option options [Truthy, Falsey] :disable_aws_builtins do not load builtins
276
+ # @yield base context
219
277
  def initialize(name, options={}, &block)
220
- @name = name
278
+ @name = name.to_sym
221
279
  @sparkle_path = options[:sparkle_path] ||
222
280
  self.class.custom_paths[:sparkle_path] ||
223
281
  File.join(Dir.pwd, 'cloudformation')
@@ -244,15 +302,21 @@ class SparkleFormation
244
302
  end
245
303
  end
246
304
 
247
- # block:: block to execute
248
- # Loads block
249
- def load_block(block)
305
+ # Add block to load order
306
+ #
307
+ # @param block [Proc]
308
+ # @return [TrueClass]
309
+ def block(block)
250
310
  @components[:__base__] = self.class.build(&block)
251
311
  @load_order << :__base__
312
+ true
252
313
  end
314
+ alias_method :load_block, :block
253
315
 
254
- # args:: symbols or paths for component loads
255
- # Loads components into instance
316
+ # Load components into instance
317
+ #
318
+ # @param args [String, Symbol] Symbol component names or String paths
319
+ # @return [self]
256
320
  def load(*args)
257
321
  args.each do |thing|
258
322
  if(thing.is_a?(Symbol))
@@ -268,12 +332,17 @@ class SparkleFormation
268
332
  end
269
333
 
270
334
  # Registers block into overrides
335
+ #
336
+ # @param args [Hash] optional arguments to provide state
337
+ # @yield override block
271
338
  def overrides(args={}, &block)
272
339
  @overrides << {:args => args, :block => block}
273
340
  self
274
341
  end
275
342
 
276
- # Returns compiled Mash instance
343
+ # Compile the formation
344
+ #
345
+ # @return [SparkleStruct]
277
346
  def compile
278
347
  compiled = SparkleStruct.new
279
348
  @load_order.each do |key|
@@ -288,4 +357,14 @@ class SparkleFormation
288
357
  compiled
289
358
  end
290
359
 
360
+ # @return [Hash] dumped hash
361
+ def dump
362
+ MultiJson.load(self.to_json)
363
+ end
364
+
365
+ # @return [String] dumped hash JSON
366
+ def to_json
367
+ MultiJson.dump(compile.dump!)
368
+ end
369
+
291
370
  end