coral_core 0.2.26 → 0.2.30

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.
Files changed (46) hide show
  1. data/Gemfile +7 -2
  2. data/Gemfile.lock +84 -15
  3. data/VERSION +1 -1
  4. data/coral_core.gemspec +51 -16
  5. data/lib/{coral_core/command.rb → coral/command/shell.rb} +12 -116
  6. data/lib/coral/machine/fog.rb +215 -0
  7. data/lib/coral/network/default.rb +26 -0
  8. data/lib/coral/node/rackspace.rb +23 -0
  9. data/lib/coral_core.rb +249 -134
  10. data/lib/coral_core/config.rb +233 -275
  11. data/lib/coral_core/config/collection.rb +57 -0
  12. data/lib/coral_core/config/options.rb +70 -0
  13. data/lib/coral_core/config/project.rb +225 -0
  14. data/lib/coral_core/core.rb +19 -173
  15. data/lib/coral_core/event/puppet_event.rb +98 -0
  16. data/lib/coral_core/mixin/config_collection.rb +52 -0
  17. data/lib/coral_core/mixin/config_ops.rb +51 -0
  18. data/lib/coral_core/mixin/config_options.rb +38 -0
  19. data/lib/coral_core/mixin/lookup.rb +211 -0
  20. data/lib/coral_core/mixin/macro/object_interface.rb +292 -0
  21. data/lib/coral_core/mixin/macro/plugin_interface.rb +277 -0
  22. data/lib/coral_core/mixin/settings.rb +46 -0
  23. data/lib/coral_core/mixin/sub_config.rb +208 -0
  24. data/lib/coral_core/mod/hash.rb +29 -0
  25. data/lib/{hiera_backend.rb → coral_core/mod/hiera_backend.rb} +0 -0
  26. data/lib/coral_core/plugin.rb +261 -0
  27. data/lib/coral_core/plugin/command.rb +95 -0
  28. data/lib/coral_core/plugin/machine.rb +152 -0
  29. data/lib/coral_core/plugin/network.rb +24 -0
  30. data/lib/coral_core/plugin/node.rb +184 -0
  31. data/lib/coral_core/plugin_base.rb +147 -0
  32. data/lib/coral_core/repository.rb +471 -82
  33. data/lib/coral_core/util/cli.rb +293 -0
  34. data/lib/coral_core/util/data.rb +178 -8
  35. data/lib/coral_core/util/disk.rb +13 -0
  36. data/lib/coral_core/util/git.rb +35 -10
  37. data/lib/coral_core/{interface.rb → util/interface.rb} +31 -21
  38. data/lib/coral_core/util/process.rb +43 -0
  39. data/locales/en.yml +8 -0
  40. data/spec/coral_core/interface_spec.rb +45 -45
  41. metadata +109 -34
  42. data/.gitmodules +0 -12
  43. data/lib/coral_core/memory.rb +0 -226
  44. data/lib/coral_core/util/git/base.rb +0 -65
  45. data/lib/coral_core/util/git/lib.rb +0 -89
  46. data/lib/coral_core/util/git/remote.rb +0 -12
@@ -3,369 +3,327 @@ module Coral
3
3
  class Config
4
4
 
5
5
  #-----------------------------------------------------------------------------
6
- # Global configuration
6
+ # Global interface
7
+
8
+ extend Mixin::ConfigOptions
9
+ extend Mixin::ConfigCollection
10
+ extend Mixin::Lookup
11
+ extend Mixin::ConfigOps
12
+
13
+ #-----------------------------------------------------------------------------
14
+ # Instance generators
7
15
 
8
- @@options = {}
16
+ def self.ensure(config)
17
+ case config
18
+ when Coral::Config
19
+ return config
20
+ when Hash
21
+ return new(config)
22
+ end
23
+ return new
24
+ end
9
25
 
10
26
  #---
11
27
 
12
- def self.options(contexts, force = true)
13
- options = {}
28
+ def self.init(options, contexts = [], hierarchy = [], defaults = {})
29
+ contexts = contexts(contexts, hierarchy)
30
+ config = new(get_options(contexts), defaults)
31
+ config.import(options) unless Util::Data.empty?(options)
32
+ return config
33
+ end
34
+
35
+ #---
36
+
37
+ def self.init_flat(options, contexts = [], defaults = {})
38
+ return init(options, contexts, [], defaults)
39
+ end
40
+
41
+ #-----------------------------------------------------------------------------
42
+ # Constructor / Destructor
43
+
44
+ def initialize(data = {}, defaults = {}, force = true)
45
+ @force = force
46
+ @properties = {}
14
47
 
15
- unless contexts.is_a?(Array)
16
- contexts = [ contexts ]
48
+ if defaults.is_a?(Hash) && ! defaults.empty?
49
+ defaults = symbol_map(defaults)
17
50
  end
18
- contexts.each do |name|
19
- if @@options.has_key?(name)
20
- options = Util::Data.merge([ options, @@options[name] ], force)
21
- end
51
+
52
+ case data
53
+ when Coral::Config
54
+ @properties = Util::Data.merge([ defaults, data.export ], force)
55
+ when Hash
56
+ @properties = {}
57
+ if data.is_a?(Hash)
58
+ @properties = Util::Data.merge([ defaults, symbol_map(data) ], force)
59
+ end
22
60
  end
23
- return options
24
61
  end
25
62
 
26
63
  #---
27
64
 
28
- def self.set_options(context, options, force = true)
29
- current_options = ( @@options.has_key?(context) ? @@options[context] : {} )
30
- @@options[context] = Util::Data.merge([ current_options, options ], force)
65
+ #def inspect
66
+ # "#<#{self.class}: >"
67
+ #end
68
+
69
+ #-----------------------------------------------------------------------------
70
+ # Property accessors / modifiers
71
+
72
+ def fetch(data, keys, default = nil, format = false)
73
+ if keys.is_a?(String) || keys.is_a?(Symbol)
74
+ keys = [ keys ]
75
+ end
76
+ key = keys.shift.to_sym
77
+
78
+ if data.has_key?(key)
79
+ value = data[key]
80
+
81
+ if keys.empty?
82
+ return filter(value, format)
83
+ else
84
+ return fetch(data[key], keys, default, format)
85
+ end
86
+ end
87
+ return filter(default, format)
31
88
  end
89
+ protected :fetch
32
90
 
33
91
  #---
34
92
 
35
- def self.clear_options(contexts)
36
- unless contexts.is_a?(Array)
37
- contexts = [ contexts ]
93
+ def modify(data, keys, value = nil)
94
+ if keys.is_a?(String) || keys.is_a?(Symbol)
95
+ keys = [ keys ]
38
96
  end
39
- contexts.each do |name|
40
- @@options.delete(name)
97
+
98
+ key = keys.shift.to_sym
99
+ has_key = data.has_key?(key)
100
+ existing = {
101
+ :key => key,
102
+ :value => ( has_key ? data[key] : nil )
103
+ }
104
+
105
+ if keys.empty?
106
+ existing[:value] = data[key] if has_key
107
+
108
+ if value.nil?
109
+ data.delete(key) if has_key
110
+ else
111
+ data[key] = value
112
+ end
113
+ else
114
+ data[key] = {} unless has_key
115
+ existing = modify(data[key], keys, value)
41
116
  end
117
+
118
+ return existing
42
119
  end
120
+ protected :modify
43
121
 
44
- #-----------------------------------------------------------------------------
122
+ #---
123
+
124
+ def get(keys, default = nil, format = false)
125
+ return fetch(@properties, array(keys).flatten, default, format)
126
+ end
45
127
 
46
- @@properties = {}
128
+ #---
129
+
130
+ def [](name, default = nil, format = false)
131
+ get(name, default, format)
132
+ end
47
133
 
48
134
  #---
49
135
 
50
- def self.properties
51
- return @@properties
136
+ def get_array(keys, default = [])
137
+ return get(keys, default, :array)
52
138
  end
53
139
 
54
140
  #---
55
141
 
56
- def self.set_property(name, value)
57
- #dbg(value, "result -> #{name}")
58
- @@properties[name] = value
59
- save_properties
142
+ def get_hash(keys, default = {})
143
+ return get(keys, default, :hash)
60
144
  end
61
145
 
62
146
  #---
63
147
 
64
- def self.clear_property(name)
65
- @@properties.delete(name)
66
- save_properties
148
+ def init(keys, default = nil)
149
+ return set(keys, get(keys, default))
67
150
  end
151
+
152
+ #---
153
+
154
+ def set(keys, value)
155
+ modify(@properties, array(keys).flatten, value)
156
+ return self
157
+ end
158
+
159
+ #---
68
160
 
161
+ def []=(name, value)
162
+ set(name, value)
163
+ end
164
+
69
165
  #---
70
166
 
71
- def self.save_properties
72
- log_options = options('coral_log')
167
+ def delete(keys, default = nil)
168
+ existing = modify(@properties, array(keys).flatten, nil)
169
+ return existing[:value] if existing[:value]
170
+ return default
171
+ end
172
+
173
+ #---
174
+
175
+ def clear
176
+ @properties = {}
177
+ return self
178
+ end
179
+
180
+ #-----------------------------------------------------------------------------
181
+ # Import / Export
182
+
183
+ def import_base(properties, options = {})
184
+ config = Config.new(options, { :force => @force }).set(:context, :hash)
185
+ import_type = config.get(:import_type, :override)
73
186
 
74
- unless Util::Data.empty?(log_options['config_log'])
75
- config_log = log_options['config_log']
187
+ case properties
188
+ when Hash
189
+ data = [ @properties, symbol_map(properties) ]
190
+ data = data.reverse if import_type != :override
76
191
 
77
- if log_options['config_store']
78
- Util::Disk.write(config_log, JSON.pretty_generate(@@properties))
79
- Util::Disk.close(config_log)
192
+ @properties = Util::Data.merge(data, config)
193
+
194
+ when String, Symbol
195
+ properties = lookup(properties.to_s, {}, config)
196
+
197
+ data = [ @properties, symbol_map(properties) ]
198
+ data = data.reverse if import_type != :override
199
+
200
+ @properties = Util::Data.merge(data, config)
201
+
202
+ when Array
203
+ properties.each do |item|
204
+ import_base(item, config)
80
205
  end
81
206
  end
207
+
208
+ return self
82
209
  end
210
+ protected :import_base
83
211
 
84
- #-----------------------------------------------------------------------------
85
- # Hiera configuration
212
+ #---
86
213
 
87
- @@hiera = nil
214
+ def import(properties, options = {})
215
+ return import_base(properties, options)
216
+ end
88
217
 
89
218
  #---
90
219
 
91
- def self.hiera_config
92
- config_file = Puppet.settings[:hiera_config]
93
- config = {}
94
-
95
- if File.exist?(config_file)
96
- config = Hiera::Config.load(config_file)
97
- else
98
- Coral.ui.warn("Config file #{config_file} not found, using Hiera defaults")
99
- end
220
+ def defaults(defaults, options = {})
221
+ config = new(options).set(:import_type, :default)
222
+ return import_base(defaults, config)
223
+ end
100
224
 
101
- config[:logger] = 'puppet'
102
- return config
225
+ #---
226
+
227
+ def export
228
+ return @properties
103
229
  end
104
230
 
105
- #---
231
+ #-----------------------------------------------------------------------------
232
+ # Utilities
106
233
 
107
- def self.hiera
108
- @@hiera = Hiera.new(:config => hiera_config) unless @@hiera
109
- return @@hiera
234
+ def self.symbol_map(data)
235
+ return Util::Data.symbol_map(data)
110
236
  end
111
237
 
112
238
  #---
113
-
114
- def hiera
115
- return self.class.hiera
239
+
240
+ def symbol_map(data)
241
+ return self.class.symbol_map(data)
116
242
  end
117
243
 
118
- #-----------------------------------------------------------------------------
119
- # Configuration lookup
120
-
121
- def self.initialized?(options = {})
122
- config = Config.ensure(options)
123
- begin
124
- require 'hiera_puppet'
125
-
126
- scope = config.get(:scope, {})
127
-
128
- sep = config.get(:sep, '::')
129
- prefix = config.get(:prefix, true)
130
- prefix_text = prefix ? sep : ''
131
-
132
- init_fact = prefix_text + config.get(:init_fact, 'hiera_ready')
133
- coral_fact = prefix_text + config.get(:coral_fact, 'coral_exists')
134
-
135
- if Puppet::Parser::Functions.function('hiera')
136
- if scope.respond_to?('[]')
137
- return true if Util::Data.true?(scope[init_fact]) && Util::Data.true?(scope[coral_fact])
138
- else
139
- return true
140
- end
141
- end
142
-
143
- rescue Exception # Prevent abortions.
144
- end
145
- return false
244
+ #---
245
+
246
+ def self.string_map(data)
247
+ return Util::Data.string_map(data)
146
248
  end
147
249
 
148
250
  #---
149
-
150
- def self.lookup(name, default = nil, options = {})
151
- config = Config.ensure(options)
152
- value = nil
153
-
154
- context = config.get(:context, :priority)
155
- scope = config.get(:scope, {})
156
- override = config.get(:override, nil)
157
-
158
- base_names = config.get(:search, nil)
159
- sep = config.get(:sep, '::')
160
- prefix = config.get(:prefix, true)
161
- prefix_text = prefix ? sep : ''
162
-
163
- debug = config.get(:debug, false)
164
-
165
- search_name = config.get(:search_name, true)
166
- reverse_lookup = config.get(:reverse_lookup, true)
167
-
168
- dbg(default, "lookup -> #{name}") if debug
169
-
170
- if Config.initialized?(options)
171
- unless scope.respond_to?("[]")
172
- scope = Hiera::Scope.new(scope)
173
- end
174
- value = hiera.lookup(name, nil, scope, override, context)
175
- dbg(value, "hiera lookup -> #{name}") if debug
176
- end
177
-
178
- if Util::Data.undef?(value) && ( scope.respond_to?("[]") || scope.respond_to?("lookupvar") )
179
- log_level = Puppet::Util::Log.level
180
- Puppet::Util::Log.level = :err # Don't want failed parameter lookup warnings here.
251
+
252
+ def string_map(data)
253
+ return self.class.string_map(data)
254
+ end
255
+
256
+ #-----------------------------------------------------------------------------
181
257
 
182
- if base_names
183
- if base_names.is_a?(String)
184
- base_names = [ base_names ]
185
- end
186
- base_names = base_names.reverse if reverse_lookup
187
-
188
- dbg(base_names, 'lookup search path') if debug
189
- base_names.each do |item|
190
- if scope.respond_to?("lookupvar")
191
- value = scope.lookupvar("#{prefix_text}#{item}#{sep}#{name}")
192
- else
193
- value = scope["#{prefix_text}#{item}#{sep}#{name}"]
194
- end
195
- dbg(value, "scope lookup #{prefix_text}#{item}#{sep}#{name}") if debug
196
- break unless Util::Data.undef?(value)
197
- end
198
- end
199
- if Util::Data.undef?(value) && search_name
200
- if scope.respond_to?("lookupvar")
201
- value = scope.lookupvar("#{prefix_text}#{name}")
202
- else
203
- value = scope["#{prefix_text}#{name}"]
204
- end
205
- dbg(value, "scope lookup #{prefix_text}#{name}") if debug
206
- end
207
- Puppet::Util::Log.level = log_level
208
- end
209
- value = default if Util::Data.undef?(value)
210
- value = Util::Data.value(value)
211
-
212
- if ! @@properties.has_key?(name) || ! Util::Data.undef?(value)
213
- set_property(name, value)
214
- end
215
-
216
- dbg(value, "lookup result -> #{name}") if debug
217
- return value
258
+ def self.filter(data, method = false)
259
+ return Util::Data.filter(data, method)
218
260
  end
219
261
 
220
262
  #---
221
-
222
- def self.normalize(data, override = nil, options = {})
223
- config = Config.ensure(options)
224
- results = {}
225
-
226
- debug = config.get(:debug, false)
227
-
228
- unless Util::Data.undef?(override)
229
- case data
230
- when String, Symbol
231
- data = [ data, override ] if data != override
232
- when Array
233
- data << override unless data.include?(override)
234
- when Hash
235
- data = [ data, override ]
236
- end
237
- end
238
-
239
- dbg(data, 'config normalize data') if debug
240
- dbg(override, 'config normalize override') if debug
241
-
242
- case data
243
- when String, Symbol
244
- results = Config.lookup(data.to_s, {}, config)
245
-
246
- when Array
247
- data.each do |item|
248
- if item.is_a?(String) || item.is_a?(Symbol)
249
- item = Config.lookup(item.to_s, {}, config)
250
- end
251
- unless Util::Data.undef?(item)
252
- results = Util::Data.merge([ results, item ], config)
253
- end
254
- end
255
263
 
256
- when Hash
257
- results = data
258
- end
259
-
260
- dbg(results, 'config normalize results') if debug
261
-
262
- return results
264
+ def filter(data, method = false)
265
+ return self.class.filter(data, method)
263
266
  end
264
267
 
265
268
  #-----------------------------------------------------------------------------
266
- # Instance generators
267
-
268
- def self.ensure(config)
269
- case config
270
- when Coral::Config
271
- return config
272
- when Hash
273
- return Config.new(config)
274
- end
275
- return Config.new
269
+
270
+ def self.array(data, default = [], split_string = false)
271
+ return Util::Data.array(data, default, split_string)
276
272
  end
277
273
 
278
274
  #---
279
275
 
280
- def self.init(options, contexts = [], defaults = {})
281
- config = Coral::Config.new(Coral::Config.options(contexts), defaults)
282
- config.import(options) unless Coral::Util::Data.empty?(options)
283
- return config
276
+ def array(data, default = [], split_string = false)
277
+ return self.class.array(data, default, split_string)
284
278
  end
285
-
286
- #-----------------------------------------------------------------------------
287
- # Configuration instance
288
-
289
- def initialize(data = {}, defaults = {}, force = true)
290
- @force = force
291
- @options = {}
292
-
293
- if defaults.is_a?(Hash) && ! defaults.empty?
294
- symbolized = {}
295
- defaults.each do |key, value|
296
- symbolized[key.to_sym] = value
297
- end
298
- defaults = symbolized
299
- end
300
279
 
301
- case data
302
- when Coral::Config
303
- @options = Util::Data.merge([ defaults, data.options ], force)
304
- when Hash
305
- @options = {}
306
- if data.is_a?(Hash)
307
- symbolized = {}
308
- data.each do |key, value|
309
- symbolized[key.to_sym] = value
310
- end
311
- @options = Util::Data.merge([ defaults, symbolized ], force)
312
- end
313
- end
280
+ #---
281
+
282
+ def self.hash(data, default = {})
283
+ data = data.export if data.is_a?(Coral::Config)
284
+ return Util::Data.hash(data, default)
314
285
  end
315
286
 
316
287
  #---
317
288
 
318
- def import(data, options = {})
319
- config = Config.new(options, { :force => @force }).set(:context, :hash)
320
-
321
- case data
322
- when Hash
323
- symbolized = {}
324
- data.each do |key, value|
325
- symbolized[key.to_sym] = value
326
- end
327
- @options = Util::Data.merge([ @options, symbolized ], config)
328
-
329
- when String
330
- data = Util::Data.lookup(data, {}, config)
331
- Util::Data.merge([ @options, data ], config)
332
-
333
- when Array
334
- data.each do |item|
335
- import(item, config)
336
- end
337
- end
289
+ def hash(data, default = {})
290
+ return self.class.hash(data, default)
291
+ end
338
292
 
339
- return self
293
+ #---
294
+
295
+ def self.string(data, default = '')
296
+ return Util::Data.string(data, default)
340
297
  end
341
298
 
342
299
  #---
343
300
 
344
- def set(name, value)
345
- @options[name.to_sym] = value
346
- return self
301
+ def string(data, default = '')
302
+ return self.class.string(data, default)
347
303
  end
348
-
349
- def []=(name, value)
350
- set(name, value)
304
+
305
+ #---
306
+
307
+ def self.symbol(data, default = :undefined)
308
+ return Util::Data.symbol(data, default)
351
309
  end
352
310
 
353
311
  #---
354
-
355
- def get(name, default = nil)
356
- name = name.to_sym
357
- return @options[name] if @options.has_key?(name)
358
- return default
359
- end
360
312
 
361
- def [](name, default = nil)
362
- get(name, default)
313
+ def symbol(data, default = :undefined)
314
+ return self.class.symbol(data, default)
315
+ end
316
+
317
+ #---
318
+
319
+ def self.test(data)
320
+ return Util::Data.test(data)
363
321
  end
364
322
 
365
323
  #---
366
324
 
367
- def options
368
- return @options
369
- end
325
+ def test(data)
326
+ return self.class.test(data)
327
+ end
370
328
  end
371
329
  end