lorj 1.0.3 → 1.0.4

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/example/students_1/students.rb +5 -6
  3. data/example/students_2/students.rb +4 -5
  4. data/example/students_3/students.rb +4 -5
  5. data/example/students_4/students.rb +4 -5
  6. data/example/students_5/students.rb +5 -5
  7. data/lib/core/core.rb +6 -1
  8. data/lib/core/core_controller.rb +1 -9
  9. data/lib/core/core_internal.rb +2 -1
  10. data/lib/core/core_model.rb +2 -10
  11. data/lib/core/core_object_data.rb +18 -0
  12. data/lib/core/core_object_params.rb +43 -4
  13. data/lib/core/core_process.rb +1 -9
  14. data/lib/core/core_process_setup.rb +32 -6
  15. data/lib/core/core_setup_ask.rb +41 -33
  16. data/lib/core/core_setup_encrypt.rb +29 -6
  17. data/lib/core/core_setup_init.rb +2 -2
  18. data/lib/core/definition.rb +33 -10
  19. data/lib/core/definition_internal.rb +10 -14
  20. data/lib/core/lorj_basedefinition.rb +16 -24
  21. data/lib/core/lorj_baseprocess.rb +113 -44
  22. data/lib/core/lorj_data.rb +2 -9
  23. data/lib/core/lorj_keypath.rb +5 -2
  24. data/lib/core_process/cloud/process/common.rb +4 -7
  25. data/lib/core_process/cloud/process/connection.rb +44 -45
  26. data/lib/core_process/cloud/process/external_network.rb +24 -28
  27. data/lib/core_process/cloud/process/flavor.rb +31 -34
  28. data/lib/core_process/cloud/process/images.rb +12 -15
  29. data/lib/core_process/cloud/process/internet_network.rb +13 -14
  30. data/lib/core_process/cloud/process/internet_server.rb +9 -10
  31. data/lib/core_process/cloud/process/keypairs.rb +34 -27
  32. data/lib/core_process/cloud/process/network.rb +21 -23
  33. data/lib/core_process/cloud/process/public_ip.rb +17 -18
  34. data/lib/core_process/cloud/process/router.rb +86 -92
  35. data/lib/core_process/cloud/process/rules.rb +30 -31
  36. data/lib/core_process/cloud/process/security_groups.rb +21 -22
  37. data/lib/core_process/cloud/process/server.rb +30 -31
  38. data/lib/core_process/cloud/process/server_log.rb +13 -14
  39. data/lib/core_process/cloud/process/subnetwork.rb +25 -40
  40. data/lib/logging.rb +4 -17
  41. data/lib/lorj/version.rb +1 -1
  42. data/lib/lorj.rb +2 -1
  43. data/lib/lorj_account.rb +137 -90
  44. data/lib/lorj_config.rb +13 -19
  45. data/lib/lorj_defaults.rb +46 -292
  46. data/lib/lorj_meta.rb +729 -0
  47. data/lib/prc.rb +119 -30
  48. data/lib/prc_base_config.rb +53 -47
  49. data/lib/prc_core_config.rb +837 -565
  50. data/lib/prc_section_config.rb +44 -16
  51. data/lib/providers/hpcloud/hpcloud.rb +1 -1
  52. data/lib/providers/openstack/openstack.rb +278 -21
  53. data/lib/providers/openstack/openstack_create.rb +205 -0
  54. data/lib/providers/openstack/openstack_delete.rb +28 -0
  55. data/lib/providers/openstack/openstack_get.rb +39 -0
  56. data/lib/providers/openstack/openstack_process.rb +26 -0
  57. data/lib/providers/openstack/openstack_query.rb +96 -0
  58. data/lib/providers/openstack/openstack_update.rb +35 -0
  59. data/lib/rh.rb +91 -6
  60. data/lorj-spec/defaults.yaml +18 -12
  61. data/lorj.gemspec +1 -0
  62. data/spec/01_hash_rh_spec.rb +41 -2
  63. data/spec/02_prc_base_config_spec.rb +1 -1
  64. data/spec/03_prc_section_config_spec.rb +1 -1
  65. data/spec/04_prc_core_config_spec.rb +148 -4
  66. data/spec/09_prc_spec.rb +104 -0
  67. data/spec/{00_lorj_log_spec.rb → 10_lorj_log_spec.rb} +23 -2
  68. data/spec/11_lorj_config_spec.rb +9 -27
  69. data/spec/12_lorj_account_spec.rb +36 -20
  70. data/spec/20_lorj_meta_spec.rb +271 -0
  71. data/spec/21_lorj_defaults_spec.rb +85 -0
  72. metadata +31 -4
data/lib/lorj_meta.rb ADDED
@@ -0,0 +1,729 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require 'rubygems'
19
+ require 'yaml'
20
+
21
+ # Lorj module implements Lorj::Config
22
+ # Lorj exposes defaults, as attribute to access the Lorj::Defaults instance.
23
+ module Lorj
24
+ # Private functions for MetaAppConfig
25
+ class MetaAppConfig < PRC::CoreConfig
26
+ private
27
+
28
+ # Used anytime config is updated (config data load or initialization)
29
+ #
30
+ # This function rebuild the section/key mapping
31
+ # Usually, executed while initializing or while loading a config.
32
+ def build_section_mapping
33
+ return unless p_exist?(:keys => [:sections])
34
+
35
+ # The primary data key should change from key to section & key.
36
+ data = p_get(:keys => [:sections], :merge => true)
37
+
38
+ return if data.nil?
39
+ section_map = {}
40
+
41
+ data.each do |section, values|
42
+ next if values.nil?
43
+ values.keys.each do |key|
44
+ section_map[key] = [] unless section_map.key?(key)
45
+ next if section_map[key].include?(section)
46
+
47
+ section_map[key] << section
48
+ end
49
+ end
50
+ p_set(:keys => [:keys], :value => section_map, :name => 'map')
51
+ end
52
+
53
+ # set section data mapping
54
+ #
55
+ def update_map(section, data)
56
+ keys = [:keys, data]
57
+ map = p_get(:keys => keys, :name => 'map')
58
+ if map.nil?
59
+ map = [section]
60
+ else
61
+ map << section unless map.include?(section)
62
+ end
63
+ p_set(:keys => keys, :name => 'map', :value => map)
64
+ end
65
+
66
+ # delete section data mapping
67
+ #
68
+ def delete_map(section, data)
69
+ keys = [:keys, data]
70
+ map = p_set(:keys => keys, :name => 'map')
71
+ return if map.nil?
72
+
73
+ map.remove section
74
+ end
75
+
76
+ # parameters tester functions
77
+ #
78
+ # * *Args*
79
+ # Each data are defined by a couple parameters.
80
+ # - 1st one is the value to check
81
+ # - 2nd one is the expected class (Class object) or
82
+ # acceptable classes (Array of class).
83
+ #
84
+ # * *Returns*
85
+ # - false if value is not of the expected Class.
86
+ # - true if all parameters are as expected.
87
+ #
88
+ def check_par(*parameters)
89
+ parameters.each_index do |index|
90
+ next unless index.odd?
91
+
92
+ if parameters[index].is_a?(Array)
93
+ unless parameters[index].include?(parameters[index - 1].class)
94
+ return false
95
+ end
96
+ end
97
+
98
+ if parameters[index].is_a?(Class)
99
+ return false unless parameters[index - 1].is_a?(parameters[index])
100
+ end
101
+ end
102
+ true
103
+ end
104
+
105
+ # build keys for set and del
106
+ # We assume type, section, data_keys to be with appropriate type.
107
+ def build_keys(type, section, data_keys)
108
+ keys = [type, section]
109
+
110
+ return keys.concat(data_keys) if data_keys.is_a?(Array)
111
+ keys << data_keys
112
+ end
113
+
114
+ # Define the meta_data Application layer
115
+ # It requires a Hash to initialize this layer until
116
+ # a file load is done instead. (Planned for Lorj 2.0)
117
+ def define_meta_app_layer(data)
118
+ data.delete(:keys) if data.is_a?(Hash) && data.key?(:keys)
119
+
120
+ PRC::CoreConfig.define_layer(:name => 'app',
121
+ :config => PRC::BaseConfig.new(data),
122
+ :set => false)
123
+ end
124
+
125
+ # Define the meta_data section/keys mapping layer
126
+ def define_meta_map_layer
127
+ PRC::CoreConfig.define_layer(:name => 'map', :set => true)
128
+ end
129
+
130
+ # Define the meta_data Application layer
131
+ def define_meta_controller_layer
132
+ PRC::CoreConfig.define_layer(:name => 'controller', :set => true,
133
+ :load => true)
134
+ end
135
+ end
136
+
137
+ # This class is the Meta Application configuration class accessible from
138
+ # PrcLib.metadata
139
+ #
140
+ # A unique class instance load data from Lorj::Defaults thanks to the
141
+ # defaults.yaml.
142
+ # In the near future, sections `:setup` and `:sections` will be moved to
143
+ # a different file and loaded by this instance itself.
144
+ #
145
+ # It implements Meta Config layers to help in loading default application meta
146
+ # data, and any controller/process redefinition.
147
+ #
148
+ # The defaults.yaml :sections and :setup is defined as follow:
149
+ #
150
+ # * :setup: Contains :ask_step array
151
+ # - :ask_step:
152
+ #
153
+ # Array of group of keys/values to setup. Each group will be
154
+ # internally identified by a index starting at 0. parameters are as
155
+ # follow:
156
+ # - :desc: string to print out before group setup
157
+ #
158
+ # ERB template enable: To get config data in ERB context, use
159
+ # config[...]
160
+ #
161
+ # - :explanation: longer string to display after :desc:
162
+ #
163
+ # It is printed out in brown color.
164
+ #
165
+ # It supports ERB template. To get config data, type
166
+ # <%= config[...] %>
167
+ #
168
+ # In your defaults.yaml file, write multiline with |- after the key.
169
+ #
170
+ # Ex: if config['text'] returns 'text', defaults.yaml can have the
171
+ # following explanation.
172
+ #
173
+ # :setup:
174
+ # :ask_step:
175
+ # - :desc: 'Small description'
176
+ # :explanation: |-
177
+ # My complete explanation is in
178
+ # multiline <%= config['text'] %>
179
+ #
180
+ # By default, thanks to data model dependency, the group is
181
+ # automatically populated. So, you need update this part only for data
182
+ # that are not found from the dependency.
183
+ #
184
+ #
185
+ # - :add: array of keys to add manually in the group. The Array can be
186
+ # written with [] or list of dash elements
187
+ #
188
+ # Example of a defaults.yaml content:
189
+ #
190
+ # :setup:
191
+ # :ask_step:
192
+ # - :desc: 'Small description'
193
+ # :add: [:key_pair_files, :ssh_user]
194
+ #
195
+ # * :section: Contains a list of sections with several keys and attributes
196
+ # and eventually :default:
197
+ #
198
+ # This list of sections and keys will be used to build the account files
199
+ # with the lorj Lorj::Core.setup function.
200
+ # Those data is accessible through the Lorj.defaults.get_meta,
201
+ # Lorj.defaults.get_meta_auto or Lorj.defaults.get_meta_section
202
+ #
203
+ # please note that Lorj.defaults.get_meta uses the controller config layer
204
+ # to redefine defaults application meta data on controller needs.
205
+ # See BaseDefinition.define_data for details.
206
+ #
207
+ # Ex:
208
+ #
209
+ # # Use Lorj.defaults.data exceptionnaly
210
+ # Lorj.defaults.data.merge({sections:
211
+ # {:mysection:
212
+ # {key:
213
+ # {
214
+ # data1: 'test1',
215
+ # data2: 'test2'
216
+ # }
217
+ # }
218
+ # }
219
+ # })
220
+ #
221
+ # puts Lorj.defaults.get_meta(:mysection, :key)
222
+ # # => { data1: 'test1', data2: 'test2' }
223
+ # puts Lorj.defaults.get_meta(:mysection)
224
+ # # => {:key => { data1: 'test1', data2: 'test2' }}
225
+ # puts Lorj.defaults.get_meta_section(:key)
226
+ # # => :mysection
227
+ # puts Lorj.defaults.get_meta_auto(:key)
228
+ # # => { data1: 'test1', data2: 'test2' }
229
+ #
230
+ # - :default: This section define updatable data available from config.yaml.
231
+ # But will never be added in an account file.
232
+ #
233
+ # It contains a list of key and options.
234
+ #
235
+ # - :<aKey>: Possible options
236
+ # - :desc: default description for that <aKey>
237
+ #
238
+ # - :<aSectionName>: Name of the section which should contains a list
239
+ # - :<aKeyName>: Name of the key to setup.
240
+ # - :desc:
241
+ #
242
+ # Description of that key, printed out at setup time. default: nil
243
+ #
244
+ # - :explanation: Multi line explanation. In yaml, use |- to write
245
+ # multilines
246
+ #
247
+ # Print a multiline explanation before ask the key value.
248
+ # ERB template enable. To get config data, type <%= config[...] %>
249
+ #
250
+ # - :encrypted: true if this has to be encrypted with ~/.cache/forj/.key
251
+ #
252
+ # - :readonly: true if this key is not modifiable by a simple.
253
+ # Lorj::Account::set function. false otherwise.
254
+ # Default: false
255
+ #
256
+ # - :account_exclusive: true to limit the data to account config layer.
257
+ #
258
+ # - :account: Set to true for setup to ask this data to the user during
259
+ # setup process. default: false
260
+ #
261
+ # - :validate: Ruby Regex to validate the end user input.
262
+ #
263
+ # Ex: :validate: !ruby/regexp /^\w?\w*$/
264
+ #
265
+ # - :default: Default value. Replace /:default/<data>
266
+ #
267
+ # - :default_value: default value proposed to the user.
268
+ #
269
+ # - :ask_step: Define the group number to attach the key to be asked.
270
+ #
271
+ # By default, setup will determine the step, thanks to lorj object
272
+ # dependencies tree.
273
+ #
274
+ # This number start at 0. Each step can be defined by
275
+ # /:setup/:ask_step/<steps> list. See :setup section.
276
+ #
277
+ # ex:
278
+ #
279
+ # :sections:
280
+ # :mysection:
281
+ # :mydata:
282
+ # :setup:
283
+ # :ask_step: 2
284
+ #
285
+ # - :ask_sort: Number which represents the ask order in the
286
+ # step group. (See /:setup/:ask_step for details)
287
+ #
288
+ # - :after: <Data> Name of the previous <Data> to ask before the
289
+ # current one.
290
+ #
291
+ # - :depends_on: Identify :data type required to be set before the
292
+ # current one.
293
+ #
294
+ # - :value_mapping: list of values to map as defined by the controller
295
+ #
296
+ # - :controller: mapping for get controller value from process
297
+ # values
298
+ #
299
+ # <value> : <map> value map equivalence. See data_value_mapping
300
+ # function
301
+ # - :process: mapping for get process value from controller values
302
+ #
303
+ # <value> : <map> value map equivalence. See data_value_mapping
304
+ # function
305
+ #
306
+ # - :list_values: Provide capabililities to get a list and choose
307
+ # from.
308
+ #
309
+ # - :query_type: It can be:
310
+ #
311
+ # - *:query_call* to execute a query on flavor, query_params is
312
+ # empty for all.
313
+ # Data are extracted thanks to :values.
314
+ #
315
+ # - *:process_call* to execute a process function to get the values.
316
+ # Data are extracted thanks to :values.
317
+ #
318
+ # - *:controller_call* to execute a controller query. Data are
319
+ # extracted thanks to :values.
320
+ #
321
+ # - *:values* to get list of fixed values from :values.
322
+ #
323
+ # - :object:
324
+ #
325
+ # Used with :query_type=:query_call. object type symbol to query.
326
+ #
327
+ # - :query
328
+ #
329
+ # Used with :query_type=:process_call. process function name to call
330
+ #
331
+ # - :query_call:
332
+ #
333
+ # Used with :query_type=:controller_call. Handler function to use.
334
+ # (query_e, create_e, ...)
335
+ # The function called must return an Array.
336
+ #
337
+ # Used with :query_type=:process_call. Function name to call
338
+ #
339
+ # - :query_params:
340
+ #
341
+ # Used with :query_type=:query_call. Query hash defining filtering
342
+ # capabilities.
343
+ #
344
+ # Used with :query_type=:process_call. hParams data passed to the
345
+ # process function.
346
+ #
347
+ # - :values: List of fields to get values or list of fixed values.
348
+ #
349
+ # Depends on query type.
350
+ #
351
+ # - :validate:
352
+ #
353
+ # if :list_strict, the value is limited to the possible values from
354
+ # the list
355
+ # - :pre_step_function: Process called before asking the data.
356
+ #
357
+ # if it returns true, user interaction is cancelled.
358
+ #
359
+ # - :post_step_function:Process called after asking the data.
360
+ #
361
+ # if it returns false, the user is requested to re-enter a new value.
362
+ #
363
+ class MetaAppConfig < PRC::CoreConfig
364
+ # Implements a 2 layers metadata config.
365
+ #
366
+ def initialize(data)
367
+ config_layers = []
368
+
369
+ # Application layer
370
+ config_layers << define_meta_app_layer(data)
371
+
372
+ # mapping section/keys layer
373
+ config_layers << define_meta_map_layer
374
+
375
+ # controller Config layer
376
+ config_layers << define_meta_controller_layer
377
+
378
+ initialize_layers(config_layers)
379
+
380
+ build_section_mapping
381
+ end
382
+
383
+ # Loop on Config metadata
384
+ #
385
+ # * *Args* :
386
+ # - +code+ : Block of code on `section`, `key`, `value`
387
+ #
388
+ # * *Returns* :
389
+ # - nothing
390
+ def meta_each
391
+ data = p_get(:keys => [:sections], :merge => true)
392
+
393
+ data.each do |section, hValue|
394
+ hValue.each do |key, value|
395
+ yield section, key, value
396
+ end
397
+ end
398
+ end
399
+
400
+ # return section/data existence
401
+ #
402
+ # * *Args* :
403
+ # - +section+ : Section to search for data.
404
+ # - +data+ : data name to check
405
+ #
406
+ # * *Returns* :
407
+ # - true/false
408
+ def meta_exist?(section, key)
409
+ p_exist?(:keys => [:sections, section, key])
410
+ end
411
+
412
+ # return 1st section/data existence.
413
+ #
414
+ # If a key name is found in several different section,
415
+ #
416
+ # auto_* functions, usually, will get the first section
417
+ # from a key/sections mapping Array.
418
+ #
419
+ # The list of sections for one key is build thanks to
420
+ # build_section_mapping.
421
+ #
422
+ # * *Args* :
423
+ # - +data+ : data name to check
424
+ #
425
+ # * *Returns* :
426
+ # - true/false
427
+ def auto_meta_exist?(data)
428
+ return nil unless data
429
+
430
+ section = first_section(data)
431
+ p_exist?(:keys => [:sections, section, data])
432
+ end
433
+
434
+ # return the 1st section name of a data.
435
+ #
436
+ # * *Args* :
437
+ # - +data+ : data name to search
438
+ #
439
+ # * *Returns* :
440
+ # - 1st section name found.
441
+ def first_section(data)
442
+ return nil unless p_exist?(:keys => [:keys, data])
443
+ arr = p_get(:keys => [:keys, data])
444
+ return nil unless arr.is_a?(Array) && arr[0]
445
+ arr[0]
446
+ end
447
+
448
+ # return the list of sections name of a data.
449
+ #
450
+ # * *Args* :
451
+ # - +data+ : Optional. data name to search.
452
+ # If no name given, returns all existing sections.
453
+ #
454
+ # * *Returns* :
455
+ # - Array of sections name.
456
+ def sections(data = nil)
457
+ return p_get(:keys => [:sections]).keys if data.nil?
458
+
459
+ return nil unless p_exist?(:keys => [:keys, data])
460
+ p_get(:keys => [:keys, data])
461
+ end
462
+
463
+ # return the list of valid keys found in meta data.
464
+ #
465
+ # * *Args* :
466
+ #
467
+ # * *Returns* :
468
+ # - Array of data name.
469
+ def datas
470
+ p_get(:keys => [:keys], :name => 'map').keys
471
+ end
472
+
473
+ # Get model setup/data options. It returns the list of options, against
474
+ # layers, of all Hash options, cloned and merged.
475
+ # Warning! This function assumes data found to be a Hash or Array.
476
+ # To get the top layer data, use #setup_data(options)
477
+ #
478
+ # * *Args* :
479
+ # - +options+ : Array of setup options tree
480
+ #
481
+ # * *Returns* :
482
+ # - Merged cloned options values.
483
+ # OR
484
+ # - nil if:
485
+ # - missing section and data name as parameter.
486
+ # - data was not found. defined in /:sections/<section>/<data
487
+ # - data found is not an Array or a Hash.
488
+ #
489
+ def setup_options(*options)
490
+ keys = [:setup]
491
+ keys.concat(options)
492
+ p_get(:keys => keys, :merge => true)
493
+ end
494
+
495
+ # Get setup options. It returns the the top layer data for options requested
496
+ #
497
+ # * *Args* :
498
+ # - +options+ : Array of options tree.
499
+ #
500
+ # * *Returns* :
501
+ # - top layer data found.
502
+ # OR
503
+ # - nil if:
504
+ # - data was not found. defined in /:setup/options...
505
+ #
506
+ def setup_data(*options)
507
+ keys = [:setup]
508
+ keys.concat(options)
509
+ p_get(:keys => keys)
510
+ end
511
+
512
+ # Get model section/data options. It returns the list of options, against
513
+ # layers, of all Hash options, cloned and merged.
514
+ #
515
+ # * *Args* :
516
+ # - +section+ : section name
517
+ # - +data+ : data name
518
+ # - +options+ : options tree.
519
+ #
520
+ # * *Returns* :
521
+ # - Merged cloned data options values.
522
+ # OR
523
+ # - nil if:
524
+ # - missing section and data name as parameter.
525
+ # - data was not found. defined in /:sections/<section>/<data
526
+ # - data found is not an Array or a Hash.
527
+ #
528
+ def section_data(section, key, *options)
529
+ return nil if section.nil? || key.nil?
530
+ keys = [:sections]
531
+ keys << section << key
532
+ keys.concat(options)
533
+ p_get(:keys => keys, :merge => true)
534
+ end
535
+
536
+ # Get model data options. Section name is determined by the associated
537
+ # data name
538
+ #
539
+ # auto_* functions, usually, will get the first section
540
+ # from a key/sections mapping Array.
541
+ #
542
+ # The list of sections for one key is build thanks to
543
+ # build_section_mapping.
544
+ #
545
+ # * *Args* :
546
+ # - +data+ : data name
547
+ # - options+ : options tree.
548
+ # * *Returns* :
549
+ # - data options values
550
+ # OR
551
+ # - nil if:
552
+ # - missing data name as parameter.
553
+ # - data was not found. defined in /:sections/<section>/<data
554
+ #
555
+ def auto_section_data(data, *options)
556
+ return nil if data.nil?
557
+ section = first_section(data)
558
+ section_data(section, data, *options)
559
+ end
560
+
561
+ # layer setting function
562
+ #
563
+ # * *Args*
564
+ # - +type+ : Define the section type name.
565
+ # Predefined section type are :setup and :sections
566
+ # - +section+ : Symbol. Section name of the data to define.
567
+ # - +data+ : Symbol or Array of Symbols. Name of the data
568
+ # - +options+ : Hash. List of options
569
+ # - +layer+ : optional. Layer name to define. All layers are authorized,
570
+ # except 'app'/'keys'. 'app' is the protected application layer data.
571
+ # By default, the layer configured is 'controller'
572
+ #
573
+ # * *Returns*
574
+ # - The value set or nil
575
+ # OR
576
+ # - nil if type, section are not Symbol.
577
+ # - nil if data is not a Symbol or an Array of Symbol
578
+ # - nil if options is not a Hash
579
+ # - nil if layer is not a String or Nil.
580
+ # - nil if data is :keys or first element of the data is :keys.
581
+ # :keys is built internally to keep sections/keys mapping updated.
582
+ #
583
+ def set(type, section, data_keys, options, layer = 'controller')
584
+ return nil unless check_par(type, Symbol,
585
+ section, Symbol,
586
+ data_keys, [Symbol, Array],
587
+ options, Hash,
588
+ layer, [String, NilClass])
589
+
590
+ keys = build_keys(type, section, data_keys)
591
+
592
+ # :keys is a special sections used internally.
593
+ return nil if keys[1] == :keys
594
+
595
+ update_map(section, keys[2]) if keys[0] == :sections
596
+
597
+ layer = 'controller' if layer.nil? || %w(app map).include?(layer)
598
+
599
+ p_set(:keys => keys, :name => layer, :value => options)
600
+ end
601
+
602
+ # layer setting function
603
+ #
604
+ # * *Args*
605
+ # - +type+ : :sections by default. Define the section type name.
606
+ # - +section+ : Symbol. Section name of the data to define.
607
+ # - +keys+ : 1 Symbol or more Symbols. Name of the data and options.
608
+ # - +options+ : Hash. List of options
609
+ #
610
+ # * *Returns*
611
+ # - The value set or nil
612
+ #
613
+ def []=(type, section, *keys, options)
614
+ return nil if keys.length == 0
615
+ set(type, section, keys, options)
616
+ end
617
+
618
+ # section/data removal function
619
+ #
620
+ # * *Args*
621
+ # - +section+ : Symbol. Section name of the data to define.
622
+ # - +data+ : Symbol or Array of Symbols. Name of the data
623
+ # - +layer+ : optional. Layer name to define. All layers are authorized,
624
+ # except 'app'. 'app' is the protected application layer data.
625
+ # By default, the layer configured is 'controller'
626
+ # * *Returns*
627
+ # - The value set or nil
628
+ #
629
+ def del(type, section, data_keys, layer = 'controller')
630
+ return nil unless check_par(type, Symbol,
631
+ section, Symbol,
632
+ data_keys, [Symbol, Array],
633
+ layer, [String, NilClass])
634
+
635
+ keys = build_keys(type, section, data_keys)
636
+
637
+ layer = 'controller' if layer.nil? || %w(app map).include?(layer)
638
+
639
+ delete_map(section, keys[2]) if keys[0] == :sections
640
+
641
+ p_del(:keys => keys, :name => layer)
642
+ end
643
+
644
+ # Controller data definition which will enhance data Application definition.
645
+ # This function replace any controller definition.
646
+ # To update/add options to an existing controller data, use #update_data.
647
+ # You can also use [], []=, etc... provided by parent class.
648
+ # This will work only if the 'controller' is the highest layer.
649
+ #
650
+ # * *Args*:
651
+ # - +section+ : Symbol. Section name of the data to define.
652
+ # - +data+ : Symbol. Name of the data
653
+ # - +options+ : Hash. List of options
654
+ # - +layer+ : optional. Layer name to define. All layers are authorized,
655
+ # except 'app'. 'app' is the protected application layer data.
656
+ # By default, the layer configured is 'controller'
657
+ def define_controller_data(section, data, options, layer = 'controller')
658
+ return nil unless check_par(section, Symbol,
659
+ data, Symbol,
660
+ options, Hash,
661
+ layer, [String, NilClass])
662
+
663
+ keys = [:sections]
664
+ keys << section << data
665
+
666
+ layer = 'controller' if layer.nil? || layer == 'app'
667
+
668
+ update_map(section, data)
669
+ p_set(:keys => keys, :name => layer, :value => options)
670
+ end
671
+
672
+ # Controller data definition which will enhance data Application definition.
673
+ # This function replace any controller definition.
674
+ # To replace or redefine options to an existing controller data, use
675
+ # #define_data.
676
+ # You can also use [], []=, etc... provided by parent class.
677
+ # This will work only if the 'controller' is the highest layer.
678
+ #
679
+ # * *Args*:
680
+ # - +section+ : Symbol. Section name of the data to define.
681
+ # - +data+ : Symbol. Name of the data
682
+ # - +options+ : Hash. List of options to add or update.
683
+ # - +layer+ : optional. Layer name to define. All layers are authorized,
684
+ # except 'app'. 'app' is the protected application layer data.
685
+ # By default, the layer configured is 'controller'
686
+ def update_controller_data(section, data, options, layer = 'controller')
687
+ return nil unless check_par(section, Symbol,
688
+ data, Symbol,
689
+ options, Hash,
690
+ layer, [String, NilClass])
691
+
692
+ keys = [:sections, section, data]
693
+ value = p_get(:keys => keys, :name => 'controller')
694
+
695
+ layer = 'controller' if layer.nil? || layer == 'app'
696
+
697
+ p_set(:keys => keys, :name => layer, :value => value.merge(options))
698
+ end
699
+ end
700
+
701
+ module_function
702
+
703
+ # Lorj::defaults exposes the application defaults and Config Lorj metadata.
704
+ #
705
+ # You can set the Application layer of meta data, replacing load from
706
+ # defaults.yaml
707
+ #
708
+ # * *Args*
709
+ # - data : Optionnal initialized Application layer meta data.
710
+ def data(data = nil)
711
+ return @metadata unless @metadata.nil?
712
+
713
+ unless data.is_a?(Hash)
714
+ data = {}
715
+ # TODO: Replace load from defaults.yaml to a dedicated meta file def.
716
+ if Lorj.defaults.data.key?(:setup)
717
+ data[:setup] = Lorj.defaults.data[:setup]
718
+ Lorj.defaults.data.delete(:setup)
719
+ end
720
+ if Lorj.defaults.data.key?(:sections)
721
+ data[:sections] = Lorj.defaults.data[:sections]
722
+ Lorj.defaults.data.delete(:sections)
723
+ end
724
+ end
725
+ @metadata = Lorj::MetaAppConfig.new data
726
+
727
+ @metadata
728
+ end
729
+ end