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
@@ -0,0 +1,26 @@
1
+
2
+ module Coral
3
+ module Network
4
+ class Default < Plugin::Network
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Cloud plugin interface
8
+
9
+ def normalize
10
+ super
11
+ end
12
+
13
+ #-----------------------------------------------------------------------------
14
+ # Checks
15
+
16
+
17
+ #-----------------------------------------------------------------------------
18
+ # Property accessors / modifiers
19
+
20
+
21
+ #-----------------------------------------------------------------------------
22
+ # Coral cloud operations
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+
2
+ module Coral
3
+ module Node
4
+ class Rackspace < Plugin::Node
5
+
6
+ #-----------------------------------------------------------------------------
7
+ # Node plugin interface
8
+
9
+ def normalize
10
+ #super
11
+ dbg('hello from rackspace node')
12
+ end
13
+
14
+ #-----------------------------------------------------------------------------
15
+ # Checks
16
+
17
+
18
+ #-----------------------------------------------------------------------------
19
+ # Property accessors / modifiers
20
+
21
+ end
22
+ end
23
+ end
@@ -13,6 +13,7 @@
13
13
  module Kernel
14
14
 
15
15
  def dbg(data, label = '')
16
+ # Invocations of this function should NOT be committed to the project
16
17
  require 'pp'
17
18
 
18
19
  puts '>>----------------------'
@@ -26,8 +27,9 @@ module Kernel
26
27
 
27
28
  #---
28
29
 
29
- def locate(command)
30
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
30
+ def coral_locate(command)
31
+ command = command.to_s
32
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
31
33
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
32
34
  exts.each do |ext|
33
35
  exe = File.join(path, "#{command}#{ext}")
@@ -36,129 +38,103 @@ module Kernel
36
38
  end
37
39
  return nil
38
40
  end
41
+
42
+ #---
43
+
44
+ def coral_require(base_dir, name)
45
+ name = name.to_s
46
+
47
+ require File.join(base_dir, "#{name}.rb")
48
+ directory = File.join(base_dir, name)
49
+
50
+ if File.directory?(directory)
51
+ Dir.glob(File.join(directory, '**', '*.rb')).each do |sub_file|
52
+ require sub_file
53
+ end
54
+ end
55
+ end
39
56
  end
40
57
 
41
58
  #-------------------------------------------------------------------------------
42
- # Properties and
59
+ # Top level properties
43
60
 
44
- home = File.dirname(__FILE__)
45
- dependencies = File.join(home, 'dependency')
46
-
47
- git_location = locate('git')
61
+ lib_dir = File.dirname(__FILE__)
62
+ core_dir = File.join(lib_dir, 'coral_core')
63
+ mixin_dir = File.join(core_dir, 'mixin')
64
+ macro_dir = File.join(mixin_dir, 'macro')
65
+ event_dir = File.join(core_dir, 'event')
66
+ template_dir = File.join(core_dir, 'template')
67
+ util_dir = File.join(core_dir, 'util')
68
+ mod_dir = File.join(core_dir, 'mod')
48
69
 
49
70
  #-------------------------------------------------------------------------------
71
+ # Coral requirements
72
+
73
+ git_location = coral_locate('git')
50
74
 
51
- $:.unshift(home) unless
52
- $:.include?(home) || $:.include?(File.expand_path(home))
75
+ $:.unshift(lib_dir) unless $:.include?(lib_dir) || $:.include?(File.expand_path(lib_dir))
53
76
 
54
77
  #---
55
78
 
56
79
  require 'rubygems'
57
80
 
58
- #---
81
+ require 'i18n'
82
+ require 'log4r'
83
+ require 'deep_merge'
84
+ require 'yaml'
85
+ require 'multi_json'
86
+ require 'digest/sha1'
59
87
 
60
- begin
61
- require 'log4r'
62
-
63
- rescue LoadError
64
- log4r_lib = File.join(dependencies, 'log4r', 'lib')
65
-
66
- $:.push(log4r_lib)
67
- require File.join(log4r_lib, 'log4r.rb')
68
- end
88
+ require 'puppet'
89
+ require 'fog'
69
90
 
70
91
  #---
71
92
 
72
- begin
73
- require 'deep_merge'
74
-
75
- rescue LoadError
76
- deep_merge_lib = File.join(dependencies, 'deep_merge', 'lib')
77
-
78
- $:.push(deep_merge_lib)
79
- require File.join(deep_merge_lib, 'deep_merge.rb')
80
- end
93
+ # TODO: Make this dynamically settable
81
94
 
82
- #---
83
-
84
- begin
85
- require 'json'
86
-
87
- rescue LoadError
88
- json_lib = File.join(dependencies, 'json', 'lib')
89
-
90
- $:.push(json_lib)
91
- require File.join(json_lib, 'json.rb')
92
- end
95
+ I18n.load_path << File.expand_path(File.join('..', 'locales', 'en.yml'), lib_dir)
93
96
 
94
97
  #---
95
98
 
96
99
  if git_location
97
- begin
98
- require 'git'
99
-
100
- rescue LoadError
101
- git_lib = File.join(dependencies, 'git', 'lib')
102
-
103
- $:.push(git_lib)
104
- require File.join(git_lib, 'git.rb')
105
- end
100
+ require 'grit'
101
+ coral_require(util_dir, :git)
106
102
  end
107
103
 
108
104
  #---
109
105
 
110
- # Include pre core utilities (no internal dependencies)
111
- [ :data, :disk ].each do |name|
112
- require File.join('coral_core', 'util', name.to_s + ".rb")
106
+ # Object modifications (100% pure monkey patches)
107
+ Dir.glob(File.join(mod_dir, '*.rb')).each do |file|
108
+ require file
113
109
  end
114
110
 
115
- if git_location
116
- require File.join('coral_core', 'util', 'git.rb')
111
+ #---
117
112
 
118
- # Include Git overrides
119
- Dir.glob(File.join(home, 'coral_core', 'util', 'git', '*.rb')).each do |file|
120
- require file
121
- end
113
+ # Mixins for classes
114
+ Dir.glob(File.join(mixin_dir, '*.rb')).each do |file|
115
+ require file
122
116
  end
123
-
124
- # Include core
125
- [ :config, :interface, :core, :resource, :template ].each do |name|
126
- require File.join('coral_core', name.to_s + ".rb")
117
+ Dir.glob(File.join(macro_dir, '*.rb')).each do |file|
118
+ require file
127
119
  end
128
120
 
129
- # Include post core utilities
130
- # ( normally inherit from core and have no reverse dependencies with
131
- # core classes )
132
- #
133
- [ :shell ].each do |name|
134
- require File.join('coral_core', 'util', name.to_s + ".rb")
135
- end
121
+ #---
136
122
 
137
- # Include data model
138
- [ :event, :command ].each do |name|
139
- require File.join('coral_core', name.to_s + ".rb")
140
- end
123
+ coral_require(util_dir, :data)
124
+ coral_require(core_dir, :config)
125
+ coral_require(util_dir, :interface)
126
+ coral_require(core_dir, :core)
141
127
 
142
- if git_location
143
- [ :repository, :memory ].each do |name|
144
- require File.join('coral_core', name.to_s + ".rb")
145
- end
128
+ # Include core utilities
129
+ [ :cli, :disk, :process, :shell ].each do |name|
130
+ coral_require(util_dir, name)
146
131
  end
147
132
 
148
- # Include specialized events
149
- Dir.glob(File.join(home, 'coral_core', 'event', '*.rb')).each do |file|
150
- require file
151
- end
152
-
153
- # Include bundled templates
154
- Dir.glob(File.join(home, 'coral_core', 'template', '*.rb')).each do |file|
155
- require file
133
+ # Include core systems
134
+ [ :event, :template, :repository, :resource, :plugin_base, :plugin ].each do |name|
135
+ coral_require(core_dir, name)
156
136
  end
157
137
 
158
- #---
159
-
160
- require 'hiera_backend.rb'
161
-
162
138
  #*******************************************************************************
163
139
  # Coral Core Library
164
140
  #
@@ -172,48 +148,167 @@ module Coral
172
148
 
173
149
  #---
174
150
 
175
- @@ui = Coral::Core.ui
151
+ @@config_file = 'coral.json'
176
152
 
177
- #---
153
+ #-----------------------------------------------------------------------------
178
154
 
179
155
  def self.ui
180
- return @@ui
156
+ return Core.ui
157
+ end
158
+
159
+ #---
160
+
161
+ def self.logger
162
+ return Core.logger
181
163
  end
182
164
 
183
165
  #-----------------------------------------------------------------------------
184
- # Initialization
185
166
 
186
- def self.load(base_path)
187
- if File.exists?(base_path)
188
- Dir.glob(File.join(base_path, '*.rb')).each do |file|
189
- require file
190
- end
191
- Dir.glob(File.join(base_path, 'event', '*.rb')).each do |file|
192
- require file
193
- end
194
- Dir.glob(File.join(base_path, 'template', '*.rb')).each do |file|
195
- require file
196
- end
197
- end
167
+ def self.config_file=file_name
168
+ @@config_file = file_name
198
169
  end
199
170
 
200
171
  #---
201
172
 
173
+ def self.config_file
174
+ return @@config_file
175
+ end
176
+
177
+ #-----------------------------------------------------------------------------
178
+ # Initialization
179
+
202
180
  @@initialized = false
203
181
 
204
182
  def self.initialize
205
183
  unless @@initialized
206
184
  Config.set_property('time', Time.now.to_i)
207
185
 
208
- # Include Coral extensions
209
- Puppet::Node::Environment.new.modules.each do |mod|
210
- load(File.join(mod.path, 'lib', 'coral'))
211
- end
186
+ begin
187
+ # Include Coral plugins
188
+ Puppet::Node::Environment.new.modules.each do |mod|
189
+ lib_path = File.join(mod.path, 'lib', 'coral')
190
+ Plugin.register(lib_path)
191
+ end
192
+ rescue
193
+ end
194
+
195
+ Plugin.initialize
212
196
 
213
197
  @@initialized = true
214
198
  end
215
199
  end
216
200
 
201
+ #---
202
+
203
+ def self.initialized?
204
+ return @@initialized
205
+ end
206
+
207
+ #-----------------------------------------------------------------------------
208
+ # Plugins
209
+
210
+ def self.plugin(type, provider, options = {})
211
+ default_provider = Plugin.type_default(type)
212
+
213
+ if options.is_a?(Hash) || options.is_a?(Coral::Config)
214
+ config = Config.ensure(options)
215
+ provider = config.get(:provider, provider)
216
+ name = config.get(:name, ( provider ? provider : default_provider ))
217
+ options = config.export
218
+ end
219
+ provider = default_provider unless provider # Sanity checking (see plugins)
220
+ existing_instance = Plugin.get_instance(type, name) if name
221
+
222
+ return existing_instance if existing_instance
223
+ return Plugin.create_instance(type, provider, options)
224
+ end
225
+
226
+ #---
227
+
228
+ def self.plugins(type, data, build_hash = false, keep_array = false)
229
+ group = ( build_hash ? {} : [] )
230
+ klass = class_const([ :coral, :plugin, type ])
231
+ data = klass.build_info(type, data) if klass.respond_to?(:build_info)
232
+
233
+ data.each do |options|
234
+ if plugin = plugin(type, options[:provider], options)
235
+ if build_hash
236
+ group[plugin.name] = plugin
237
+ else
238
+ group << plugin
239
+ end
240
+ end
241
+ end
242
+ return group.shift if ! build_hash && group.length == 1 && ! keep_array
243
+ return group
244
+ end
245
+
246
+ #---
247
+
248
+ def self.get_plugin(type, name)
249
+ return Plugin.get_instance(type, name)
250
+ end
251
+
252
+ #---
253
+
254
+ def self.remove_plugin(plugin)
255
+ return Plugin.remove_instance(plugin)
256
+ end
257
+
258
+ #-----------------------------------------------------------------------------
259
+ # Core plugin type facade
260
+
261
+ def self.network(name, options = {}, provider = nil)
262
+ plugin = plugin(:network, provider, options)
263
+ plugin.name = name
264
+ return plugin
265
+ end
266
+
267
+ #---
268
+
269
+ def self.networks(data, build_hash = false, keep_array = false)
270
+ return plugins(:network, data, build_hash, keep_array)
271
+ end
272
+
273
+ #---
274
+
275
+ def self.node(name, options = {}, provider = nil)
276
+ plugin = plugin(:node, provider, options)
277
+ plugin.name = name
278
+ return plugin
279
+ end
280
+
281
+ #---
282
+
283
+ def self.nodes(data, build_hash = false, keep_array = false)
284
+ return plugins(:node, data, build_hash, keep_array)
285
+ end
286
+
287
+ #---
288
+
289
+ def self.machine(options = {}, provider = nil)
290
+ plugin = plugin(:machine, provider, options)
291
+ return plugin
292
+ end
293
+
294
+ #---
295
+
296
+ def self.machines(data, build_hash = false, keep_array = false)
297
+ return plugins(:machine, data, build_hash, keep_array)
298
+ end
299
+
300
+ #---
301
+
302
+ def self.command(options, provider = nil)
303
+ return plugin(:command, provider, options)
304
+ end
305
+
306
+ #---
307
+
308
+ def self.commands(data, build_hash = false, keep_array = false)
309
+ return plugins(:command, data, build_hash, keep_array)
310
+ end
311
+
217
312
  #-----------------------------------------------------------------------------
218
313
  # External execution
219
314
 
@@ -228,33 +323,53 @@ module Coral
228
323
  raise
229
324
  end
230
325
  end
231
- end
232
-
233
- #-------------------------------------------------------------------------------
234
- # Data type alterations
235
-
236
- class Hash
237
- def search(search_key, options = {})
238
- config = Coral::Config.ensure(options)
239
- value = nil
240
326
 
241
- recurse = config.get(:recurse, false)
242
- recurse_level = config.get(:recurse_level, -1)
243
-
244
- self.each do |key, data|
245
- if key == search_key
246
- value = data
247
-
248
- elsif data.is_a?(Hash) &&
249
- recurse && (recurse_level == -1 || recurse_level > 0)
250
-
251
- recurse_level -= 1 unless recurse_level == -1
252
- value = value.search(search_key,
253
- Coral::Config.new(config).set(:recurse_level, recurse_level)
254
- )
255
- end
256
- break unless value.nil?
327
+ #-----------------------------------------------------------------------------
328
+ # Utilities
329
+
330
+ def self.class_name(name, separator = '::', want_array = FALSE)
331
+ components = []
332
+
333
+ case name
334
+ when String, Symbol
335
+ components = name.to_s.split(separator)
336
+ when Array
337
+ components = name
257
338
  end
258
- return value
339
+
340
+ components.collect! do |value|
341
+ value.to_s.strip.capitalize
342
+ end
343
+
344
+ if want_array
345
+ return components
346
+ end
347
+ return components.join(separator)
348
+ end
349
+
350
+ #---
351
+
352
+ def self.class_const(name, separator = '::')
353
+ components = class_name(name, separator, TRUE)
354
+ constant = Object
355
+
356
+ components.each do |component|
357
+ constant = constant.const_defined?(component) ?
358
+ constant.const_get(component) :
359
+ constant.const_missing(component)
360
+ end
361
+
362
+ return constant
259
363
  end
364
+
365
+ #---
366
+
367
+ def self.sha1(data)
368
+ return Digest::SHA1.hexdigest(Util::Data.to_json(data, false))
369
+ end
260
370
  end
371
+
372
+ #-------------------------------------------------------------------------------
373
+ # Coral initialization
374
+
375
+ Coral.initialize