lorj 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +46 -0
  4. data/Gemfile +15 -15
  5. data/README.md +22 -17
  6. data/Rakefile +12 -2
  7. data/bin/cloud_test.rb +13 -65
  8. data/example/students_1/process/students.rb +39 -0
  9. data/example/students_1/students.rb +22 -5
  10. data/example/students_2/process/students.rb +48 -0
  11. data/example/students_2/students.rb +39 -16
  12. data/example/students_3/controller/yaml_students.rb +50 -43
  13. data/example/students_3/controller/yaml_students_controller.rb +100 -87
  14. data/example/students_3/process/students.rb +161 -97
  15. data/example/students_3/students.rb +85 -56
  16. data/example/yaml_students/students.rb +40 -40
  17. data/example/yaml_students/yaml_students.rb +103 -90
  18. data/lib/core/core.rb +356 -696
  19. data/lib/core/core_controller.rb +227 -0
  20. data/lib/core/core_internal.rb +339 -0
  21. data/lib/core/core_model.rb +328 -0
  22. data/lib/core/core_object_data.rb +330 -0
  23. data/lib/core/core_object_params.rb +230 -0
  24. data/lib/core/core_process.rb +391 -0
  25. data/lib/core/core_process_setup.rb +353 -0
  26. data/lib/core/core_setup_ask.rb +241 -0
  27. data/lib/core/core_setup_encrypt.rb +146 -0
  28. data/lib/core/core_setup_init.rb +229 -0
  29. data/lib/core/core_setup_list.rb +160 -0
  30. data/lib/core/definition.rb +647 -469
  31. data/lib/core/definition_internal.rb +264 -308
  32. data/lib/core/lorj_basecontroller.rb +95 -0
  33. data/lib/core/lorj_basedefinition.rb +307 -0
  34. data/lib/core/lorj_baseprocess.rb +265 -0
  35. data/lib/core/lorj_data.rb +583 -0
  36. data/lib/core/lorj_keypath.rb +119 -0
  37. data/lib/core_process/cloud/process/common.rb +63 -0
  38. data/lib/core_process/cloud/process/connection.rb +93 -0
  39. data/lib/core_process/cloud/process/external_network.rb +94 -0
  40. data/lib/core_process/cloud/process/flavor.rb +99 -0
  41. data/lib/core_process/cloud/process/images.rb +87 -0
  42. data/lib/core_process/cloud/process/internet_network.rb +34 -0
  43. data/lib/core_process/cloud/process/internet_server.rb +30 -0
  44. data/lib/core_process/cloud/process/keypairs.rb +276 -0
  45. data/lib/core_process/cloud/process/network.rb +108 -0
  46. data/lib/core_process/cloud/process/public_ip.rb +100 -0
  47. data/lib/core_process/cloud/process/router.rb +260 -0
  48. data/lib/core_process/cloud/process/rules.rb +120 -0
  49. data/lib/core_process/cloud/process/security_groups.rb +121 -0
  50. data/lib/core_process/cloud/process/server.rb +127 -0
  51. data/lib/core_process/cloud/process/server_log.rb +35 -0
  52. data/lib/core_process/cloud/process/subnetwork.rb +108 -0
  53. data/lib/core_process/cloud_process.rb +30 -0
  54. data/lib/logging.rb +298 -0
  55. data/lib/lorj/version.rb +18 -1
  56. data/lib/lorj.rb +58 -18
  57. data/lib/lorj_account.rb +556 -0
  58. data/lib/lorj_config.rb +468 -0
  59. data/lib/lorj_defaults.rb +278 -0
  60. data/lib/prc.rb +136 -104
  61. data/lib/prc_base_config.rb +285 -0
  62. data/lib/prc_core_config.rb +878 -0
  63. data/lib/prc_section_config.rb +57 -0
  64. data/lib/providers/hpcloud/compute.rb +81 -93
  65. data/lib/providers/hpcloud/hpcloud.rb +462 -0
  66. data/lib/providers/hpcloud/network.rb +96 -98
  67. data/lib/providers/hpcloud/security_groups.rb +41 -40
  68. data/lib/providers/mock/mock.rb +144 -0
  69. data/lib/providers/openstack/openstack.rb +45 -0
  70. data/lib/providers/templates/compute.rb +21 -23
  71. data/lib/providers/templates/mycloud.rb +72 -0
  72. data/lib/providers/templates/network.rb +11 -12
  73. data/lib/rh.rb +339 -0
  74. data/lorj-spec/defaults.yaml +4 -0
  75. data/lorj.gemspec +6 -0
  76. data/spec/00_lorj_log_spec.rb +53 -0
  77. data/spec/01_hash_rh_spec.rb +243 -0
  78. data/spec/02_prc_base_config_spec.rb +216 -0
  79. data/spec/04_prc_core_config_spec.rb +83 -0
  80. data/spec/11_lorj_config_spec.rb +263 -0
  81. data/spec/12_lorj_account_spec.rb +181 -0
  82. metadata +76 -28
  83. data/Gemfile.lock +0 -37
  84. data/example/students_1/process/Students.rb +0 -20
  85. data/example/students_2/process/Students.rb +0 -27
  86. data/example/students_4/controller/yaml_students.rb +0 -82
  87. data/example/students_4/controller/yaml_students_controller.rb +0 -141
  88. data/example/students_4/process/students.rb +0 -112
  89. data/example/students_4/students.rb +0 -103
  90. data/lib/core/lorj-basecontroller.rb +0 -90
  91. data/lib/core/lorj-basedefinition.rb +0 -1139
  92. data/lib/core/lorj-baseprocess.rb +0 -236
  93. data/lib/core/lorj-data.rb +0 -567
  94. data/lib/core/lorj-keypath.rb +0 -115
  95. data/lib/core_process/CloudProcess.rb +0 -337
  96. data/lib/core_process/global_process.rb +0 -502
  97. data/lib/core_process/network_process.rb +0 -605
  98. data/lib/prc-account.rb +0 -339
  99. data/lib/prc-config.rb +0 -1030
  100. data/lib/prc-logging.rb +0 -261
  101. data/lib/providers/hpcloud/Hpcloud.rb +0 -426
  102. data/lib/providers/mock/Mock.rb +0 -141
  103. data/lib/providers/openstack/Openstack.rb +0 -47
  104. data/lib/providers/templates/core.rb +0 -61
  105. data/spec/forj-account_spec.rb +0 -75
  106. data/spec/forj-config_spec.rb +0 -196
@@ -0,0 +1,556 @@
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
+
20
+ module Lorj
21
+ # Simple List of accounts class.
22
+ class Accounts
23
+ # Class to query FORJ Accounts list.
24
+ def initialize
25
+ @account_path = File.join(PrcLib.data_path, 'accounts')
26
+ end
27
+
28
+ def dump
29
+ accounts = []
30
+ Dir.foreach(@account_path) do |x|
31
+ accounts << x unless x.match(/^\..?$/)
32
+ end
33
+ accounts
34
+ end
35
+ end
36
+ end
37
+
38
+ module Lorj
39
+ # AccountConfig class layer
40
+ class AccountConfig < PRC::SectionConfig
41
+ # Function to initialize read only account attribute.
42
+ def ac_new(account_name, provider = 'lorj')
43
+ @data = {}
44
+ data_options :section => :account
45
+ self[:name] = account_name
46
+ self[:provider] = provider
47
+ true
48
+ end
49
+
50
+ def data_options(options = { :section => :default })
51
+ _data_options(options)
52
+ end
53
+ end
54
+ end
55
+
56
+ module Lorj
57
+ # Lorj::Account manage a list of key/value grouped by section.
58
+ # The intent of Lorj::Account is to attach some keys/values to
59
+ # an account to help end users to switch between accounts.
60
+ #
61
+ # Lorj::Account is based on Lorj::Config (see lorj-config.rb)
62
+ # This ensure ForjConfig and Lorj::Account defines following common functions
63
+ # - set or []= (key, value)
64
+ # - get or [] (key)
65
+ #
66
+ # Those function do not expose any section name.
67
+ # It means, that keys have to be unique across sections.
68
+ # Sections are defined in the application defaults.yaml, under sections
69
+ # :sections.
70
+ #
71
+ # defaults.yaml structure is:
72
+ # sections:
73
+ # default: => defines key/values recognized by Lorj::Account to be only
74
+ # managed by ForjConfig.
75
+ # <key> :
76
+ # :desc : <value> => defines the ForjConfig key description.
77
+ # <section>: Define a section name. For each keys on this section, the
78
+ # account file will kept those data under this section.
79
+ # <key>:
80
+ # :desc: defines the key description.
81
+ # :readonly: true if this key cannot be updated by
82
+ # Lorj::Account.set
83
+ # :account_exclusive: true if this key cannot be predefined on
84
+ # ForjConfig keys list
85
+ # :default: *OBSOLETE*. It will be removed soon
86
+ # default values have to be defined as
87
+ # :default_value instead of /:default/<key>
88
+ # <ForjConfig real key name> Used to map the
89
+ # Lorj::Account key to a different ForjConfig key
90
+ # name.
91
+ # :default_value: default application value for this key.
92
+ # ':default_value' superseed /:default/<key>/<value>
93
+ # name.
94
+ #
95
+ # Currently, this class derived from Lorj::Config
96
+ # defines the following functions:
97
+ # where? exist?, get or [], set or []=, save and load.
98
+ #
99
+ # exist?, get uses the config layers to get data. By default, the order is:
100
+ # - runtime : get the data from runtime (runtimeSet/runtime_get)
101
+ # - Account : otherwise, get data from account file under section
102
+ # described in defaults.yaml (:account_section_mapping), as
103
+ # soon as this mapping exists.
104
+ # - local : otherwise, get the data from the local configuration file.
105
+ # Usually ~/.forj/config.yaml
106
+ # - application: otherwise, get the data from defaults.yaml (class Default)
107
+ class Account < Lorj::Config
108
+ attr_reader :account_name
109
+
110
+ # This object manage data located in oConfig[:hpc_accounts/AccountName]
111
+
112
+ # The class new accept to provide a local config file different than
113
+ # standard one configured by PrcLib.app_path/.config.yaml
114
+ def initialize(config_name = nil)
115
+ config_layers = []
116
+
117
+ # Application layer
118
+ config_layers << define_default_layer
119
+
120
+ # Local Config layer
121
+ config_layers << define_local_layer
122
+
123
+ # Account config layer
124
+ config_layers << define_account_layer
125
+
126
+ # runtime Config layer
127
+ config_layers << define_runtime_layer
128
+
129
+ Lorj.defaults.load # Loading global application defaults
130
+
131
+ if PrcLib.data_path.nil?
132
+ PrcLib.fatal(1, 'Internal PrcLib.data_path was not set.')
133
+ end
134
+
135
+ initialize_local(config_layers[1][:config], config_name)
136
+
137
+ initialize_account
138
+
139
+ initialize_layers(config_layers)
140
+ end
141
+
142
+ # get function.
143
+ # If the Application meta data option of the key is set with
144
+ # :account_exclusive => true, get will limit to runtime then account.
145
+ # otherwise, search in all layers.
146
+ #
147
+ # * *Args* :
148
+ # - +key+ : key name. It do not support it to be a key tree (Arrays of
149
+ # keys).
150
+ # - +default+ : default value, if not found.
151
+ # - +options+ : Options for get:
152
+ # - +:section+ : Get will use this section name instead of searching it.
153
+ # - +:name+ : layer to exclusively get data.
154
+ # - +:indexes+ : layer index to exclusively get data.
155
+ # If neither :name or :index is set, get will search
156
+ # data on all predefined layers, first found.
157
+ # * *Returns* :
158
+ # - key value.
159
+ # * *Raises* :
160
+ # Nothing
161
+ def get(key, default = nil, options = {})
162
+ key = key.to_sym if key.class == String
163
+ options = {} unless options.is_a?(Hash)
164
+
165
+ section = options[:section]
166
+ section = Lorj.defaults.get_meta_section(key) if section.nil?
167
+
168
+ options = { :keys => [key], :section => section }
169
+
170
+ indexes = _identify_indexes(options, exclusive?(key, section))
171
+
172
+ options[:data_options] = _set_data_options_per_indexes(indexes)
173
+
174
+ return _get(options) if _exist?(options)
175
+
176
+ default
177
+ end
178
+
179
+ def [](key, default = nil)
180
+ get(key, default)
181
+ end
182
+
183
+ # where? function.
184
+ # If the Application meta data option of the key is set with
185
+ # :account_exclusive => true, get will limit to runtime then account.
186
+ # otherwise, search in all layers.
187
+ #
188
+ # * *Args* :
189
+ # - +key+ : key name. It do not support it to be a key tree (Arrays of
190
+ # keys).
191
+ # - +default+ : default value, if not found.
192
+ # * *Returns* :
193
+ # - key value.
194
+ # * *Raises* :
195
+ # Nothing
196
+ def where?(key, section = nil)
197
+ key = key.to_sym if key.class == String
198
+
199
+ section = Lorj.defaults.get_meta_section(key) if section.nil?
200
+
201
+ options = { :keys => [key], :section => section }
202
+
203
+ account_exclusive = exclusive?(key, section)
204
+ if account_exclusive
205
+ indexes = [0, 1]
206
+ options[:indexes] = indexes
207
+ else
208
+ indexes = [0, 1, 2, 3]
209
+ end
210
+
211
+ options[:data_options] = _set_data_options_per_indexes(indexes)
212
+
213
+ _where?(options)
214
+ end
215
+
216
+ # check key/value existence in config layers
217
+ #
218
+ # * *Args* :
219
+ # - +key+ : key name. It do not support it to be a key tree (Arrays of
220
+ # keys).
221
+ # - +options+ : possible options:
222
+ # - +:section+ : Force to use a specific section name.
223
+ # - +:name+ : layer to exclusively get data.
224
+ # - +:indexes+ : layer index to exclusively get data.
225
+ # If neither :name or :index is set, get will search
226
+ # data on all predefined layers, first found.
227
+ #
228
+ # * *Returns* :
229
+ # - 'runtime' : if found in runtime.
230
+ # - '<AccountName>' : if found in the Account data structure.
231
+ # - 'local' : if found in the local configuration file.
232
+ # Usually ~/.forj/config.yaml
233
+ # - 'default' : if found in the Application default
234
+ # (File 'defaults.yaml') (class Default)
235
+ # * *Raises* :
236
+ # Nothing
237
+ def exist?(key, options = nil)
238
+ key = key.to_sym if key.class == String
239
+ options = {} unless options.is_a?(Hash)
240
+
241
+ section = options[:section]
242
+ section = Lorj.defaults.get_meta_section(key) if section.nil?
243
+ options = { :keys => [key], :section => section }
244
+
245
+ indexes = _identify_indexes(options, exclusive?(key, section))
246
+
247
+ options[:data_options] = _set_data_options_per_indexes(indexes)
248
+
249
+ _exist?(options)
250
+ end
251
+
252
+ # Return true if readonly. set won't be able to update this value.
253
+ # Only _set (private function) is able.
254
+ #
255
+ # * *Args* :
256
+ # - +key+ : key name. It can support it to be a key tree (Arrays of
257
+ # keys).
258
+ # - +section+ : optionnal. If missing the section name is determined by
259
+ # the data name associated
260
+ # * *Returns* :
261
+ # - true/false : readonly value
262
+ # OR
263
+ # - nil if:
264
+ # - section was not found
265
+ def readonly?(key, section = nil)
266
+ return nil unless key
267
+
268
+ key = key.to_sym if key.class == String
269
+ section = Lorj.defaults.get_meta_section(key) if section.nil?
270
+
271
+ return nil if section.nil?
272
+
273
+ result = Lorj.defaults.get_meta(section, key, :readonly)
274
+ return result if result.boolean?
275
+ false
276
+ end
277
+
278
+ # Return true if exclusive
279
+ # set won't be able to update this value.
280
+ # Only _set (private function) is able.
281
+ #
282
+ # * *Args* :
283
+ # - +key+ : key name. It can support it to be a key tree (Arrays of
284
+ # keys).
285
+ # - +section+ : optionnal. If missing the section name is determined by
286
+ # the data name associated
287
+ # * *Returns* :
288
+ # - true/false : readonly value
289
+ # OR
290
+ # - nil if:
291
+ # - section was not found
292
+ def exclusive?(key, section = nil)
293
+ return nil unless key
294
+
295
+ key = key.to_sym if key.class == String
296
+ section = Lorj.defaults.get_meta_section(key) if section.nil?
297
+
298
+ return nil if section.nil?
299
+ result = Lorj.defaults.get_meta(section, key,
300
+ :account_exclusive)
301
+ return result if result.boolean?
302
+ result
303
+ end
304
+
305
+ # This function update a section/key=value if the account structure is
306
+ # defined.
307
+ # If no section is defined, set it in runtime config.
308
+ #
309
+ # * *Args* :
310
+ # - +key+ : key name. It do not support it to be a key tree (Arrays of
311
+ # keys).
312
+ # - +value+ : value to set
313
+ # - +options+ : possible options:
314
+ # - +:section+ : Force to use a specific section name.
315
+ # - +:name+ : layer to exclusively get data.
316
+ # - +:indexes+ : layer index to exclusively get data.
317
+ # If neither :name or :index is set, set will use the
318
+ # 'runtime' layer.
319
+ #
320
+ # * *Returns* :
321
+ # - the value set
322
+ # OR
323
+ # - nil if:
324
+ # - lorj data model set this key as readonly.
325
+ # - value is nil. The value is set to nil, then.
326
+ # - key is nil. No update is done.
327
+ #
328
+ # * *Raises* :
329
+ # Nothing
330
+ def set(key, value, options = {})
331
+ parameters = validate_key_and_options(key, options)
332
+ return nil if parameters.nil?
333
+
334
+ key = parameters[0][0]
335
+ layer_name, section = parameters[1]
336
+
337
+ section = Lorj.defaults.get_meta_section(key) if section.nil?
338
+ section = :default if section.nil?
339
+
340
+ return nil if readonly?(key, section)
341
+
342
+ options = { :keys => [key], :section => section, :value => value }
343
+
344
+ options[:indexes] = index_to_update(layer_name, key, section)
345
+
346
+ _set(options)
347
+ end
348
+
349
+ def []=(key, value)
350
+ set(key, value)
351
+ end
352
+
353
+ def del(key, options = {})
354
+ parameters = validate_key_and_options(key, options)
355
+ return nil if parameters.nil?
356
+
357
+ key = parameters[0][0]
358
+ layer_name, section = parameters[1]
359
+
360
+ section = Lorj.defaults.get_meta_section(key) if section.nil?
361
+ section = :default if section.nil?
362
+
363
+ return nil if readonly?(key, section)
364
+
365
+ options = { :keys => [key], :section => section }
366
+
367
+ options[:indexes] = index_to_update(layer_name, key, section)
368
+
369
+ _del(options)
370
+ end
371
+ end
372
+
373
+ # Defines Account exclusive functions
374
+ class Account
375
+ def ac_new(sAccountName, provider_name = nil)
376
+ return nil if sAccountName.nil?
377
+ @account_name = sAccountName
378
+
379
+ account = @config_layers[1][:config]
380
+ account.erase
381
+ account.ac_new sAccountName, provider_name
382
+ end
383
+
384
+ # Load Account Information
385
+ def ac_load(sAccountName = @account_name)
386
+ @account_name = sAccountName unless !sAccountName.nil? &&
387
+ sAccountName == @account_name
388
+ return false if @account_name.nil?
389
+
390
+ account_file = File.join(@account_path, @account_name)
391
+ return false unless File.exist?(account_file)
392
+
393
+ _do_load(@config_layers[1][:config], account_file)
394
+ end
395
+
396
+ # Account save function.
397
+ # Use set/get to manage those data that you will be able to save in an
398
+ # account file.
399
+ # * *Args* :
400
+ #
401
+ # * *Returns* :
402
+ # - true if saved
403
+ # OR
404
+ # - false if:
405
+ # - the account do not set the :provider name.
406
+ # - value is nil. The value is set to nil, then.
407
+ # OR
408
+ # - nil if:
409
+ # - account_name is not set
410
+ #
411
+ # * *Raises* :
412
+ # Nothing
413
+ def ac_save
414
+ return nil if @account_name.nil?
415
+
416
+ account_file = File.join(@account_path, @account_name)
417
+
418
+ account = @config_layers[1][:config]
419
+ local = @config_layers[2][:config]
420
+
421
+ account.data_options(:section => :account)
422
+ if account[:provider].nil?
423
+ PrcLib.error "Provider name is not set. Unable to save the account '"\
424
+ "%s' to '%s'", @account_name, account_file
425
+ return false
426
+ end
427
+
428
+ account.filename = account_file
429
+ result = account.save
430
+
431
+ return result unless result
432
+
433
+ return true if local.exist?(:account_name)
434
+
435
+ local[:account_name] = @account_name
436
+ local.save
437
+
438
+ true
439
+ end
440
+ end
441
+
442
+ # Defines internal functions
443
+ class Account
444
+ # TODO: Strange function!!! To revisit
445
+
446
+ def meta_type?(key)
447
+ return nil unless key
448
+
449
+ section = Lorj.defaults.get_meta_section(key)
450
+
451
+ return section if section == :default
452
+ @account_name
453
+ end
454
+
455
+ # private functions
456
+
457
+ private
458
+
459
+ def _identify_indexes(options, account_exclusive)
460
+ index = options[:index] if options.key?(:index)
461
+ index = layer_index(options[:name]) if options.key?(:name)
462
+
463
+ if account_exclusive
464
+ indexes = [0, 1]
465
+ options[:indexes] = indexes
466
+ else
467
+ indexes = [0, 1, 2, 3]
468
+ end
469
+
470
+ indexes = [index] if !index.nil? && indexes.include?(index)
471
+ indexes
472
+ end
473
+
474
+ def _set_data_options_per_indexes(indexes)
475
+ data_options = []
476
+
477
+ indexes.each { |index| data_options << _data_options_per_layer(index) }
478
+
479
+ data_options
480
+ end
481
+
482
+ # This internal function defines default section name per config index.
483
+ # TODO: Change local and default way to get default values, not in /:default
484
+ def _data_options_per_layer(layer_index)
485
+ # runtime and local and default uses :default section
486
+ case layer_index
487
+ when 2, 3
488
+ # local & default are SectionConfig and is forced to use :default as
489
+ # section name for each data.
490
+ { :section => :default }
491
+ end
492
+ # nil: layer_index = 0 => runtime. runtime is not a SectionConfig.
493
+
494
+ # nil: layer_index = 1 => account
495
+ # account is a SectionConfig and use section value defined by the
496
+ # lorj data model. So the section name is not forced.
497
+ end
498
+
499
+ def _do_load(config, account_file)
500
+ result = config.load account_file
501
+ return result unless result == true
502
+
503
+ config.data_options :section => :account
504
+ config[:name] = @account_name unless config[:name]
505
+ unless config.exist?(:provider)
506
+ config[:provider] = nil
507
+ PrcLib.warning "'%s' defines an empty provider name.", account_file
508
+ end
509
+
510
+ if config.rh_key_to_symbol?(2)
511
+ config.rh_key_to_symbol(2)
512
+ config.save
513
+ end
514
+ true
515
+ end
516
+
517
+ def index_to_update(layer_name, key, section)
518
+ indexes = [0] # choose runtime by default.
519
+ indexes = _layer_indexes([layer_name]) unless layer_name.nil?
520
+
521
+ if layer_name.nil?
522
+ # Return runtime layer, if layer requested is not updatable.
523
+ return [0] if indexes[0] <= (exclusive?(key, section) ? 1 : 3)
524
+ end
525
+ indexes
526
+ end
527
+
528
+ def define_account_layer
529
+ PRC::CoreConfig.define_layer(:name => 'account',
530
+ :config => Lorj::AccountConfig.new,
531
+ :file_set => true,
532
+ :load => true, :save => true)
533
+ end
534
+
535
+ def initialize_account
536
+ @account_path = File.join(PrcLib.data_path, 'accounts')
537
+
538
+ PrcLib.ensure_dir_exists(@account_path)
539
+ end
540
+
541
+ def validate_key_and_options(key, options = {})
542
+ return nil unless key
543
+
544
+ key = key.to_sym if key.class == String
545
+
546
+ options = {} unless options.is_a?(Hash)
547
+
548
+ parameters = _valid_options(options, [], [:name, :section])
549
+
550
+ return nil if parameters.nil?
551
+
552
+ parameters[0] << key
553
+ parameters
554
+ end
555
+ end
556
+ end