corl 0.4.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.
- data/.document +5 -0
- data/.gitmodules +4 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +123 -0
- data/LICENSE.txt +674 -0
- data/README.rdoc +27 -0
- data/Rakefile +78 -0
- data/VERSION +1 -0
- data/bin/corl +55 -0
- data/corl.gemspec +228 -0
- data/lib/corl/action/add.rb +69 -0
- data/lib/corl/action/bootstrap.rb +83 -0
- data/lib/corl/action/clone.rb +40 -0
- data/lib/corl/action/create.rb +55 -0
- data/lib/corl/action/exec.rb +41 -0
- data/lib/corl/action/extract.rb +49 -0
- data/lib/corl/action/image.rb +30 -0
- data/lib/corl/action/images.rb +55 -0
- data/lib/corl/action/lookup.rb +35 -0
- data/lib/corl/action/machines.rb +51 -0
- data/lib/corl/action/provision.rb +37 -0
- data/lib/corl/action/remove.rb +51 -0
- data/lib/corl/action/save.rb +53 -0
- data/lib/corl/action/seed.rb +115 -0
- data/lib/corl/action/spawn.rb +75 -0
- data/lib/corl/action/start.rb +37 -0
- data/lib/corl/action/stop.rb +30 -0
- data/lib/corl/action/update.rb +37 -0
- data/lib/corl/command/shell.rb +164 -0
- data/lib/corl/configuration/file.rb +386 -0
- data/lib/corl/event/puppet.rb +90 -0
- data/lib/corl/event/regex.rb +52 -0
- data/lib/corl/extension/puppetloader.rb +24 -0
- data/lib/corl/machine/fog.rb +310 -0
- data/lib/corl/machine/physical.rb +161 -0
- data/lib/corl/network/default.rb +26 -0
- data/lib/corl/node/aws.rb +90 -0
- data/lib/corl/node/fog.rb +198 -0
- data/lib/corl/node/google.rb +115 -0
- data/lib/corl/node/local.rb +26 -0
- data/lib/corl/node/rackspace.rb +89 -0
- data/lib/corl/project/git.rb +465 -0
- data/lib/corl/project/github.rb +108 -0
- data/lib/corl/provisioner/puppetnode/resource.rb +245 -0
- data/lib/corl/provisioner/puppetnode/resource_group.rb +205 -0
- data/lib/corl/provisioner/puppetnode.rb +407 -0
- data/lib/corl/template/environment.rb +73 -0
- data/lib/corl/template/json.rb +16 -0
- data/lib/corl/template/wrapper.rb +16 -0
- data/lib/corl/template/yaml.rb +16 -0
- data/lib/corl/translator/json.rb +27 -0
- data/lib/corl/translator/yaml.rb +27 -0
- data/lib/corl.rb +173 -0
- data/lib/corl_core/codes.rb +107 -0
- data/lib/corl_core/config/collection.rb +57 -0
- data/lib/corl_core/config/options.rb +70 -0
- data/lib/corl_core/config.rb +337 -0
- data/lib/corl_core/core.rb +59 -0
- data/lib/corl_core/corl.rb +254 -0
- data/lib/corl_core/errors.rb +84 -0
- data/lib/corl_core/facade.rb +126 -0
- data/lib/corl_core/gems.rb +72 -0
- data/lib/corl_core/manager.rb +425 -0
- data/lib/corl_core/mixin/action/commit.rb +58 -0
- data/lib/corl_core/mixin/action/keypair.rb +105 -0
- data/lib/corl_core/mixin/action/node.rb +129 -0
- data/lib/corl_core/mixin/action/project.rb +53 -0
- data/lib/corl_core/mixin/action/push.rb +52 -0
- data/lib/corl_core/mixin/config/collection.rb +53 -0
- data/lib/corl_core/mixin/config/ops.rb +53 -0
- data/lib/corl_core/mixin/config/options.rb +39 -0
- data/lib/corl_core/mixin/lookup.rb +196 -0
- data/lib/corl_core/mixin/macro/object_interface.rb +361 -0
- data/lib/corl_core/mixin/macro/plugin_interface.rb +380 -0
- data/lib/corl_core/mixin/settings.rb +46 -0
- data/lib/corl_core/mixin/sub_config.rb +148 -0
- data/lib/corl_core/mod/hash.rb +29 -0
- data/lib/corl_core/mod/hiera_backend.rb +63 -0
- data/lib/corl_core/plugin/action.rb +381 -0
- data/lib/corl_core/plugin/base.rb +374 -0
- data/lib/corl_core/plugin/command.rb +98 -0
- data/lib/corl_core/plugin/configuration.rb +177 -0
- data/lib/corl_core/plugin/event.rb +53 -0
- data/lib/corl_core/plugin/extension.rb +12 -0
- data/lib/corl_core/plugin/machine.rb +266 -0
- data/lib/corl_core/plugin/network.rb +359 -0
- data/lib/corl_core/plugin/node.rb +904 -0
- data/lib/corl_core/plugin/project.rb +927 -0
- data/lib/corl_core/plugin/provisioner.rb +51 -0
- data/lib/corl_core/plugin/template.rb +80 -0
- data/lib/corl_core/plugin/translator.rb +38 -0
- data/lib/corl_core/util/cli.rb +352 -0
- data/lib/corl_core/util/data.rb +404 -0
- data/lib/corl_core/util/disk.rb +114 -0
- data/lib/corl_core/util/git.rb +47 -0
- data/lib/corl_core/util/interface.rb +319 -0
- data/lib/corl_core/util/liquid.rb +17 -0
- data/lib/corl_core/util/package.rb +93 -0
- data/lib/corl_core/util/shell.rb +239 -0
- data/lib/corl_core/util/ssh.rb +286 -0
- data/lib/facter/corl_config_ready.rb +13 -0
- data/lib/facter/corl_exists.rb +15 -0
- data/lib/facter/corl_network.rb +17 -0
- data/lib/hiera/corl_logger.rb +18 -0
- data/lib/puppet/indirector/corl.rb +27 -0
- data/lib/puppet/indirector/data_binding/corl.rb +6 -0
- data/lib/puppet/parser/functions/config_initialized.rb +26 -0
- data/lib/puppet/parser/functions/corl_include.rb +44 -0
- data/lib/puppet/parser/functions/corl_resources.rb +58 -0
- data/lib/puppet/parser/functions/deep_merge.rb +21 -0
- data/lib/puppet/parser/functions/ensure.rb +29 -0
- data/lib/puppet/parser/functions/file_exists.rb +19 -0
- data/lib/puppet/parser/functions/global_array.rb +35 -0
- data/lib/puppet/parser/functions/global_hash.rb +35 -0
- data/lib/puppet/parser/functions/global_options.rb +23 -0
- data/lib/puppet/parser/functions/global_param.rb +43 -0
- data/lib/puppet/parser/functions/interpolate.rb +26 -0
- data/lib/puppet/parser/functions/is_false.rb +21 -0
- data/lib/puppet/parser/functions/is_true.rb +21 -0
- data/lib/puppet/parser/functions/module_array.rb +38 -0
- data/lib/puppet/parser/functions/module_hash.rb +38 -0
- data/lib/puppet/parser/functions/module_options.rb +23 -0
- data/lib/puppet/parser/functions/module_param.rb +48 -0
- data/lib/puppet/parser/functions/name.rb +21 -0
- data/lib/puppet/parser/functions/render.rb +33 -0
- data/lib/puppet/parser/functions/value.rb +21 -0
- data/locales/en.yml +232 -0
- data/spec/corl_core/interface_spec.rb +489 -0
- data/spec/corl_mock_input.rb +29 -0
- data/spec/corl_test_kernel.rb +22 -0
- data/spec/spec_helper.rb +15 -0
- metadata +406 -0
@@ -0,0 +1,337 @@
|
|
1
|
+
|
2
|
+
module CORL
|
3
|
+
class Config
|
4
|
+
|
5
|
+
#-----------------------------------------------------------------------------
|
6
|
+
# Global interface
|
7
|
+
|
8
|
+
extend Mixin::ConfigOptions
|
9
|
+
extend Mixin::ConfigCollection
|
10
|
+
extend Mixin::Lookup
|
11
|
+
|
12
|
+
#-----------------------------------------------------------------------------
|
13
|
+
# Instance generators
|
14
|
+
|
15
|
+
def self.ensure(config)
|
16
|
+
case config
|
17
|
+
when CORL::Config
|
18
|
+
return config
|
19
|
+
when Hash
|
20
|
+
return new(config)
|
21
|
+
end
|
22
|
+
return new
|
23
|
+
end
|
24
|
+
|
25
|
+
#---
|
26
|
+
|
27
|
+
def self.init(options, contexts = [], hierarchy = [], defaults = {})
|
28
|
+
contexts = contexts(contexts, hierarchy)
|
29
|
+
config = new(get_options(contexts), defaults)
|
30
|
+
config.import(options) unless Util::Data.empty?(options)
|
31
|
+
return config
|
32
|
+
end
|
33
|
+
|
34
|
+
#---
|
35
|
+
|
36
|
+
def self.init_flat(options, contexts = [], defaults = {})
|
37
|
+
return init(options, contexts, [], defaults)
|
38
|
+
end
|
39
|
+
|
40
|
+
#-----------------------------------------------------------------------------
|
41
|
+
# Constructor / Destructor
|
42
|
+
|
43
|
+
def initialize(data = {}, defaults = {}, force = true)
|
44
|
+
@force = force
|
45
|
+
@properties = {}
|
46
|
+
|
47
|
+
if defaults.is_a?(Hash) && ! defaults.empty?
|
48
|
+
defaults = symbol_map(defaults)
|
49
|
+
end
|
50
|
+
|
51
|
+
case data
|
52
|
+
when CORL::Config
|
53
|
+
@properties = Util::Data.merge([ defaults, data.export ], force)
|
54
|
+
when Hash
|
55
|
+
@properties = {}
|
56
|
+
if data.is_a?(Hash)
|
57
|
+
@properties = Util::Data.merge([ defaults, symbol_map(data) ], force)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
#-----------------------------------------------------------------------------
|
63
|
+
# Checks
|
64
|
+
|
65
|
+
def has_key?(keys)
|
66
|
+
get(keys) ? true : false
|
67
|
+
end
|
68
|
+
|
69
|
+
#-----------------------------------------------------------------------------
|
70
|
+
# Property accessors / modifiers
|
71
|
+
|
72
|
+
def keys
|
73
|
+
@properties.keys
|
74
|
+
end
|
75
|
+
|
76
|
+
#---
|
77
|
+
|
78
|
+
def fetch(data, keys, default = nil, format = false)
|
79
|
+
if keys.is_a?(String) || keys.is_a?(Symbol)
|
80
|
+
keys = [ keys ]
|
81
|
+
end
|
82
|
+
key = keys.shift.to_sym
|
83
|
+
|
84
|
+
if data.has_key?(key)
|
85
|
+
value = data[key]
|
86
|
+
|
87
|
+
if keys.empty?
|
88
|
+
return filter(value, format)
|
89
|
+
else
|
90
|
+
return fetch(data[key], keys, default, format)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
return filter(default, format)
|
94
|
+
end
|
95
|
+
protected :fetch
|
96
|
+
|
97
|
+
#---
|
98
|
+
|
99
|
+
def modify(data, keys, value = nil)
|
100
|
+
if keys.is_a?(String) || keys.is_a?(Symbol)
|
101
|
+
keys = [ keys ]
|
102
|
+
end
|
103
|
+
|
104
|
+
key = keys.shift.to_sym
|
105
|
+
has_key = data.has_key?(key)
|
106
|
+
existing = {
|
107
|
+
:key => key,
|
108
|
+
:value => ( has_key ? data[key] : nil )
|
109
|
+
}
|
110
|
+
|
111
|
+
if keys.empty?
|
112
|
+
existing[:value] = data[key] if has_key
|
113
|
+
|
114
|
+
if value.nil?
|
115
|
+
data.delete(key) if has_key
|
116
|
+
else
|
117
|
+
data[key] = value
|
118
|
+
end
|
119
|
+
else
|
120
|
+
data[key] = {} unless has_key
|
121
|
+
existing = modify(data[key], keys, value)
|
122
|
+
end
|
123
|
+
|
124
|
+
return existing
|
125
|
+
end
|
126
|
+
protected :modify
|
127
|
+
|
128
|
+
#---
|
129
|
+
|
130
|
+
def get(keys, default = nil, format = false)
|
131
|
+
return fetch(@properties, array(keys).flatten, default, format)
|
132
|
+
end
|
133
|
+
|
134
|
+
#---
|
135
|
+
|
136
|
+
def [](name, default = nil, format = false)
|
137
|
+
get(name, default, format)
|
138
|
+
end
|
139
|
+
|
140
|
+
#---
|
141
|
+
|
142
|
+
def get_array(keys, default = [])
|
143
|
+
return get(keys, default, :array)
|
144
|
+
end
|
145
|
+
|
146
|
+
#---
|
147
|
+
|
148
|
+
def get_hash(keys, default = {})
|
149
|
+
return get(keys, default, :hash)
|
150
|
+
end
|
151
|
+
|
152
|
+
#---
|
153
|
+
|
154
|
+
def init(keys, default = nil)
|
155
|
+
return set(keys, get(keys, default))
|
156
|
+
end
|
157
|
+
|
158
|
+
#---
|
159
|
+
|
160
|
+
def set(keys, value)
|
161
|
+
modify(@properties, array(keys).flatten, value)
|
162
|
+
return self
|
163
|
+
end
|
164
|
+
|
165
|
+
#---
|
166
|
+
|
167
|
+
def []=(name, value)
|
168
|
+
set(name, value)
|
169
|
+
end
|
170
|
+
|
171
|
+
#---
|
172
|
+
|
173
|
+
def delete(keys, default = nil)
|
174
|
+
existing = modify(@properties, array(keys).flatten, nil)
|
175
|
+
return existing[:value] if existing[:value]
|
176
|
+
return default
|
177
|
+
end
|
178
|
+
|
179
|
+
#---
|
180
|
+
|
181
|
+
def clear
|
182
|
+
@properties = {}
|
183
|
+
return self
|
184
|
+
end
|
185
|
+
|
186
|
+
#-----------------------------------------------------------------------------
|
187
|
+
# Import / Export
|
188
|
+
|
189
|
+
def import_base(properties, options = {})
|
190
|
+
config = Config.new(options, { :force => @force }).set(:context, :hash)
|
191
|
+
import_type = config.get(:import_type, :override)
|
192
|
+
|
193
|
+
properties = properties.export if properties.is_a?(CORL::Config)
|
194
|
+
|
195
|
+
case properties
|
196
|
+
when Hash
|
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 String, Symbol
|
203
|
+
properties = self.class.lookup(properties.to_s, {}, config)
|
204
|
+
|
205
|
+
data = [ @properties, symbol_map(properties) ]
|
206
|
+
data = data.reverse if import_type != :override
|
207
|
+
|
208
|
+
@properties = Util::Data.merge(data, config)
|
209
|
+
|
210
|
+
when Array
|
211
|
+
properties.each do |item|
|
212
|
+
import_base(item, config)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
return self
|
217
|
+
end
|
218
|
+
protected :import_base
|
219
|
+
|
220
|
+
#---
|
221
|
+
|
222
|
+
def import(properties, options = {})
|
223
|
+
return import_base(properties, options)
|
224
|
+
end
|
225
|
+
|
226
|
+
#---
|
227
|
+
|
228
|
+
def defaults(defaults, options = {})
|
229
|
+
config = Config.new(options).set(:import_type, :default)
|
230
|
+
return import_base(defaults, config)
|
231
|
+
end
|
232
|
+
|
233
|
+
#---
|
234
|
+
|
235
|
+
def export
|
236
|
+
return @properties
|
237
|
+
end
|
238
|
+
|
239
|
+
#-----------------------------------------------------------------------------
|
240
|
+
# Utilities
|
241
|
+
|
242
|
+
def self.symbol_map(data)
|
243
|
+
return Util::Data.symbol_map(data)
|
244
|
+
end
|
245
|
+
|
246
|
+
#---
|
247
|
+
|
248
|
+
def symbol_map(data)
|
249
|
+
return self.class.symbol_map(data)
|
250
|
+
end
|
251
|
+
|
252
|
+
#---
|
253
|
+
|
254
|
+
def self.string_map(data)
|
255
|
+
return Util::Data.string_map(data)
|
256
|
+
end
|
257
|
+
|
258
|
+
#---
|
259
|
+
|
260
|
+
def string_map(data)
|
261
|
+
return self.class.string_map(data)
|
262
|
+
end
|
263
|
+
|
264
|
+
#-----------------------------------------------------------------------------
|
265
|
+
|
266
|
+
def self.filter(data, method = false)
|
267
|
+
return Util::Data.filter(data, method)
|
268
|
+
end
|
269
|
+
|
270
|
+
#---
|
271
|
+
|
272
|
+
def filter(data, method = false)
|
273
|
+
return self.class.filter(data, method)
|
274
|
+
end
|
275
|
+
|
276
|
+
#-----------------------------------------------------------------------------
|
277
|
+
|
278
|
+
def self.array(data, default = [], split_string = false)
|
279
|
+
return Util::Data.array(data, default, split_string)
|
280
|
+
end
|
281
|
+
|
282
|
+
#---
|
283
|
+
|
284
|
+
def array(data, default = [], split_string = false)
|
285
|
+
return self.class.array(data, default, split_string)
|
286
|
+
end
|
287
|
+
|
288
|
+
#---
|
289
|
+
|
290
|
+
def self.hash(data, default = {})
|
291
|
+
data = data.export if data.is_a?(CORL::Config)
|
292
|
+
return Util::Data.hash(data, default)
|
293
|
+
end
|
294
|
+
|
295
|
+
#---
|
296
|
+
|
297
|
+
def hash(data, default = {})
|
298
|
+
return self.class.hash(data, default)
|
299
|
+
end
|
300
|
+
|
301
|
+
#---
|
302
|
+
|
303
|
+
def self.string(data, default = '')
|
304
|
+
return Util::Data.string(data, default)
|
305
|
+
end
|
306
|
+
|
307
|
+
#---
|
308
|
+
|
309
|
+
def string(data, default = '')
|
310
|
+
return self.class.string(data, default)
|
311
|
+
end
|
312
|
+
|
313
|
+
#---
|
314
|
+
|
315
|
+
def self.symbol(data, default = :undefined)
|
316
|
+
return Util::Data.symbol(data, default)
|
317
|
+
end
|
318
|
+
|
319
|
+
#---
|
320
|
+
|
321
|
+
def symbol(data, default = :undefined)
|
322
|
+
return self.class.symbol(data, default)
|
323
|
+
end
|
324
|
+
|
325
|
+
#---
|
326
|
+
|
327
|
+
def self.test(data)
|
328
|
+
return Util::Data.test(data)
|
329
|
+
end
|
330
|
+
|
331
|
+
#---
|
332
|
+
|
333
|
+
def test(data)
|
334
|
+
return self.class.test(data)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
|
2
|
+
module CORL
|
3
|
+
class Core < Config
|
4
|
+
|
5
|
+
#-----------------------------------------------------------------------------
|
6
|
+
# Properties
|
7
|
+
|
8
|
+
@@ui = Util::Interface.new("core")
|
9
|
+
|
10
|
+
#-----------------------------------------------------------------------------
|
11
|
+
# Constructor / Destructor
|
12
|
+
|
13
|
+
def initialize(data = {}, defaults = {}, force = true)
|
14
|
+
super(data, defaults, force)
|
15
|
+
|
16
|
+
class_label = self.class.to_s.downcase.gsub(/^corl::/, '')
|
17
|
+
logger_name = delete(:logger, class_label)
|
18
|
+
interface_config = Config.new(export).defaults({ :logger => logger_name, :resource => class_label })
|
19
|
+
|
20
|
+
@ui = Util::Interface.new(interface_config)
|
21
|
+
logger.debug("Initialized instance interface")
|
22
|
+
end
|
23
|
+
|
24
|
+
#-----------------------------------------------------------------------------
|
25
|
+
# Accessor / Modifiers
|
26
|
+
|
27
|
+
attr_accessor :ui
|
28
|
+
|
29
|
+
#---
|
30
|
+
|
31
|
+
def self.ui
|
32
|
+
return @@ui
|
33
|
+
end
|
34
|
+
|
35
|
+
#---
|
36
|
+
|
37
|
+
def self.logger
|
38
|
+
return @@ui.logger
|
39
|
+
end
|
40
|
+
|
41
|
+
#---
|
42
|
+
|
43
|
+
def logger
|
44
|
+
return @ui.logger
|
45
|
+
end
|
46
|
+
|
47
|
+
#-----------------------------------------------------------------------------
|
48
|
+
# General utilities
|
49
|
+
|
50
|
+
def ui_group(resource)
|
51
|
+
ui_resource = ui.resource
|
52
|
+
ui.resource = resource
|
53
|
+
yield
|
54
|
+
|
55
|
+
ensure
|
56
|
+
ui.resource = ui_resource
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,254 @@
|
|
1
|
+
|
2
|
+
module CORL
|
3
|
+
|
4
|
+
VERSION = File.read(File.join(File.dirname(__FILE__), '..', '..', 'VERSION'))
|
5
|
+
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
|
8
|
+
def self.ui
|
9
|
+
Core.ui
|
10
|
+
end
|
11
|
+
|
12
|
+
#---
|
13
|
+
|
14
|
+
def self.logger
|
15
|
+
Core.logger
|
16
|
+
end
|
17
|
+
|
18
|
+
#---
|
19
|
+
|
20
|
+
def self.add_log_levels(*levels)
|
21
|
+
Util::Interface.add_log_levels(levels)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.log_level
|
25
|
+
Util::Interface.log_level
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.log_level=log_level
|
29
|
+
Util::Interface.log_level = log_level
|
30
|
+
end
|
31
|
+
|
32
|
+
#-----------------------------------------------------------------------------
|
33
|
+
|
34
|
+
def self.admin?
|
35
|
+
is_admin = ( ENV['USER'] == 'root' )
|
36
|
+
ext_admin = exec(:check_admin) do |op, results|
|
37
|
+
if op == :reduce
|
38
|
+
results.values.include?(true)
|
39
|
+
else
|
40
|
+
results ? true : false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
is_admin || ext_admin ? true : false
|
44
|
+
end
|
45
|
+
|
46
|
+
#-----------------------------------------------------------------------------
|
47
|
+
# Status codes
|
48
|
+
|
49
|
+
@@codes = Codes.new
|
50
|
+
|
51
|
+
def self.code
|
52
|
+
@@codes
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.codes(*codes)
|
56
|
+
Codes.codes(*codes)
|
57
|
+
end
|
58
|
+
|
59
|
+
#-----------------------------------------------------------------------------
|
60
|
+
# Initialization
|
61
|
+
|
62
|
+
def self.initialize
|
63
|
+
current_time = Time.now
|
64
|
+
|
65
|
+
Celluloid.logger = logger
|
66
|
+
|
67
|
+
logger.info("Initializing the CORL plugin system at #{current_time}")
|
68
|
+
Config.set_property('time', current_time.to_i)
|
69
|
+
|
70
|
+
connection = Manager.connection
|
71
|
+
|
72
|
+
connection.define_type :extension => nil, # Core
|
73
|
+
:configuration => :file, # Core
|
74
|
+
:action => :update, # Core
|
75
|
+
:project => :git, # Core
|
76
|
+
:network => :default, # Cluster
|
77
|
+
:node => :local, # Cluster
|
78
|
+
:machine => :physical, # Cluster
|
79
|
+
:provisioner => :puppetnode, # Cluster
|
80
|
+
:command => :shell, # Cluster
|
81
|
+
:event => :regex, # Utility
|
82
|
+
:template => :json, # Utility
|
83
|
+
:translator => :json # Utility
|
84
|
+
|
85
|
+
connection.load_plugins(true)
|
86
|
+
|
87
|
+
logger.info("Finished initializing CORL plugin system at #{Time.now}")
|
88
|
+
end
|
89
|
+
|
90
|
+
#-----------------------------------------------------------------------------
|
91
|
+
# Core plugin interface
|
92
|
+
|
93
|
+
def self.plugin_load(type, provider, options = {})
|
94
|
+
config = Config.ensure(options)
|
95
|
+
name = config.get(:name, nil)
|
96
|
+
|
97
|
+
logger.info("Fetching plugin #{type} provider #{provider} at #{Time.now}")
|
98
|
+
logger.debug("Plugin options: #{config.export.inspect}")
|
99
|
+
|
100
|
+
connection = Manager.connection
|
101
|
+
|
102
|
+
if name
|
103
|
+
logger.debug("Looking up existing instance of #{name}")
|
104
|
+
|
105
|
+
existing_instance = connection.get(type, name)
|
106
|
+
logger.info("Using existing instance of #{type}, #{name}") if existing_instance
|
107
|
+
end
|
108
|
+
|
109
|
+
return existing_instance if existing_instance
|
110
|
+
connection.create(type, provider, config.export)
|
111
|
+
end
|
112
|
+
|
113
|
+
#---
|
114
|
+
|
115
|
+
def self.plugin(type, provider, options = {})
|
116
|
+
default_provider = Manager.connection.type_default(type)
|
117
|
+
|
118
|
+
if options.is_a?(Hash) || options.is_a?(CORL::Config)
|
119
|
+
config = Config.ensure(options)
|
120
|
+
provider = config.get(:provider, provider)
|
121
|
+
options = config.export
|
122
|
+
end
|
123
|
+
provider = default_provider unless provider # Sanity checking (see plugins)
|
124
|
+
|
125
|
+
plugin_load(type, provider, options)
|
126
|
+
end
|
127
|
+
|
128
|
+
#---
|
129
|
+
|
130
|
+
def self.plugins(type, data, build_hash = false, keep_array = false)
|
131
|
+
logger.info("Fetching multiple plugins of #{type} at #{Time.now}")
|
132
|
+
|
133
|
+
group = ( build_hash ? {} : [] )
|
134
|
+
klass = class_const([ 'CORL', :plugin, type ])
|
135
|
+
data = klass.build_info(type, data) if klass.respond_to?(:build_info)
|
136
|
+
|
137
|
+
logger.debug("Translated plugin data: #{data.inspect}")
|
138
|
+
|
139
|
+
data.each do |options|
|
140
|
+
if plugin = plugin(type, options[:provider], options)
|
141
|
+
if build_hash
|
142
|
+
group[plugin.plugin_name] = plugin
|
143
|
+
else
|
144
|
+
group << plugin
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
return group.shift if ! build_hash && group.length == 1 && ! keep_array
|
149
|
+
group
|
150
|
+
end
|
151
|
+
|
152
|
+
#---
|
153
|
+
|
154
|
+
def self.get_plugin(type, name)
|
155
|
+
Manager.connection.get(type, name)
|
156
|
+
end
|
157
|
+
|
158
|
+
#---
|
159
|
+
|
160
|
+
def self.remove_plugin(plugin)
|
161
|
+
Manager.connection.remove(plugin)
|
162
|
+
end
|
163
|
+
|
164
|
+
#-----------------------------------------------------------------------------
|
165
|
+
# Plugin extensions
|
166
|
+
|
167
|
+
def self.exec(method, options = {})
|
168
|
+
Manager.connection.exec(method, options) do |op, data|
|
169
|
+
data = yield(op, data) if block_given?
|
170
|
+
data
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
#---
|
175
|
+
|
176
|
+
def self.config(type, options = {})
|
177
|
+
Manager.connection.config(method, options)
|
178
|
+
end
|
179
|
+
|
180
|
+
#---
|
181
|
+
|
182
|
+
def self.check(method, options = {})
|
183
|
+
Manager.connection.check(method, options)
|
184
|
+
end
|
185
|
+
|
186
|
+
#---
|
187
|
+
|
188
|
+
def self.value(method, value, options = {})
|
189
|
+
Manager.connection.value(method, value, options)
|
190
|
+
end
|
191
|
+
|
192
|
+
#-----------------------------------------------------------------------------
|
193
|
+
# External execution
|
194
|
+
|
195
|
+
def self.run
|
196
|
+
begin
|
197
|
+
logger.debug("Running contained process at #{Time.now}")
|
198
|
+
yield
|
199
|
+
|
200
|
+
rescue Exception => error
|
201
|
+
logger.error("CORL run experienced an error! Details:")
|
202
|
+
logger.error(error.inspect)
|
203
|
+
logger.error(error.message)
|
204
|
+
logger.error(Util::Data.to_yaml(error.backtrace))
|
205
|
+
|
206
|
+
ui.error(error.message) if error.message
|
207
|
+
raise
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
#-----------------------------------------------------------------------------
|
212
|
+
# Utilities
|
213
|
+
|
214
|
+
def self.class_name(name, separator = '::', want_array = FALSE)
|
215
|
+
components = []
|
216
|
+
|
217
|
+
case name
|
218
|
+
when String, Symbol
|
219
|
+
components = name.to_s.split(separator)
|
220
|
+
when Array
|
221
|
+
components = name
|
222
|
+
end
|
223
|
+
|
224
|
+
components.collect! do |value|
|
225
|
+
next value if value.to_s == 'CORL'
|
226
|
+
value.to_s.strip.capitalize
|
227
|
+
end
|
228
|
+
|
229
|
+
if want_array
|
230
|
+
return components
|
231
|
+
end
|
232
|
+
components.join(separator)
|
233
|
+
end
|
234
|
+
|
235
|
+
#---
|
236
|
+
|
237
|
+
def self.class_const(name, separator = '::')
|
238
|
+
components = class_name(name, separator, TRUE)
|
239
|
+
constant = Object
|
240
|
+
|
241
|
+
components.each do |component|
|
242
|
+
constant = constant.const_defined?(component) ?
|
243
|
+
constant.const_get(component) :
|
244
|
+
constant.const_missing(component)
|
245
|
+
end
|
246
|
+
constant
|
247
|
+
end
|
248
|
+
|
249
|
+
#---
|
250
|
+
|
251
|
+
def self.sha1(data)
|
252
|
+
Digest::SHA1.hexdigest(Util::Data.to_json(data, false))
|
253
|
+
end
|
254
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
module CORL
|
3
|
+
module Errors
|
4
|
+
|
5
|
+
#-----------------------------------------------------------------------------
|
6
|
+
# Base error (based on VagrantError)
|
7
|
+
|
8
|
+
class CORLError < StandardError
|
9
|
+
|
10
|
+
#---------------------------------------------------------------------------
|
11
|
+
# Error constructor / destructor
|
12
|
+
|
13
|
+
def initialize(*args)
|
14
|
+
key = args.shift if args.first.is_a?(Symbol)
|
15
|
+
message = args.shift if args.first.is_a?(Hash)
|
16
|
+
message ||= {}
|
17
|
+
|
18
|
+
@extra_data = message.dup
|
19
|
+
|
20
|
+
message[:key] ||= error_key
|
21
|
+
message[:namespace] ||= error_namespace
|
22
|
+
message[:key] = key if key
|
23
|
+
|
24
|
+
if message[:key]
|
25
|
+
message = translate_error(message)
|
26
|
+
else
|
27
|
+
message = error_message
|
28
|
+
end
|
29
|
+
|
30
|
+
super(message)
|
31
|
+
end
|
32
|
+
|
33
|
+
#---------------------------------------------------------------------------
|
34
|
+
# Property accessor / modifiers
|
35
|
+
|
36
|
+
attr_accessor :extra_data
|
37
|
+
|
38
|
+
#---
|
39
|
+
|
40
|
+
def self.error_key(key = nil, namespace = nil)
|
41
|
+
define_method(:error_key) { key }
|
42
|
+
error_namespace(namespace) if namespace
|
43
|
+
end
|
44
|
+
def error_key; nil; end # Default
|
45
|
+
|
46
|
+
#---
|
47
|
+
|
48
|
+
def self.error_message(message)
|
49
|
+
define_method(:error_message) { message }
|
50
|
+
end
|
51
|
+
def error_message; "No error message"; end # Default
|
52
|
+
|
53
|
+
#---
|
54
|
+
|
55
|
+
def self.error_namespace(namespace)
|
56
|
+
define_method(:error_namespace) { namespace }
|
57
|
+
end
|
58
|
+
def error_namespace; "corl.errors"; end # Default
|
59
|
+
|
60
|
+
#---
|
61
|
+
|
62
|
+
def self.status_code(code)
|
63
|
+
define_method(:status_code) { code }
|
64
|
+
end
|
65
|
+
def status_code; 1; end # Default
|
66
|
+
|
67
|
+
#---------------------------------------------------------------------------
|
68
|
+
# Utilities
|
69
|
+
|
70
|
+
def translate_error(options)
|
71
|
+
return nil unless options[:key]
|
72
|
+
I18n.t("#{options[:namespace]}.#{options[:key]}", options)
|
73
|
+
end
|
74
|
+
protected :translate_error
|
75
|
+
end
|
76
|
+
|
77
|
+
#-----------------------------------------------------------------------------
|
78
|
+
# Specialized errors
|
79
|
+
|
80
|
+
class BatchError < CORLError
|
81
|
+
error_key(:batch_error)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|