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.
@@ -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