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,353 @@
1
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'highline/import'
16
+
17
+ # Module Lorj which contains several classes.
18
+ #
19
+ # Those classes describes :
20
+ # - processes (BaseProcess) : How to create/delete/edit/query object.
21
+ # - controler (BaseControler) : If a provider is defined, define how will do
22
+ # object creation/etc...
23
+ # - definition(BaseDefinition): Functions to declare objects, query/data mapping
24
+ # and setup
25
+ # this task to make it to work.
26
+ module Lorj
27
+ # Adding process core functions.
28
+ class BaseDefinition
29
+ # Setup process.
30
+ # The setup process is used to ask the end user to provide some data.
31
+ # You can call it before you run an action, or during a configution setting
32
+ # of your application.
33
+ #
34
+ # setup will be exposed to the end user per several steps, and config data
35
+ # to ask in a specific order, with optionnally some explanations, possible
36
+ # values (hard coded list of values or queried from the model) and default
37
+ # value.
38
+ #
39
+ # Ex:
40
+ # Step 1 description : *Provider configuration*:
41
+ # explanation : You are going to setup your account information
42
+ # ask a config data: Enter my account name: |myuser|
43
+ # ask others data : Enter ...
44
+ # Step 2 description : *Another configuration to setup*:
45
+ # ask several data : Enter ...
46
+ # etc...
47
+ #
48
+ # Steps are predefined in the application defaults.yaml from
49
+ # /:setup/:ask_step
50
+ # Commonly, each step can define the following options:
51
+ # - :desc: Required. Define the step description.
52
+ # ERB template enable. To get config data,
53
+ # type <%= config[...] %>
54
+ # - :explanation: |- Optional. Define a multiline explanation. This is
55
+ # printed out in brown color.
56
+ # ERB template enable. To get config data, type
57
+ # <%= config[...] %>
58
+ #
59
+ # For details or more options, see core_model.rb
60
+ #
61
+ # config data are initially identified by the Object model dependency.
62
+ # (See obj_needs model declaration.)
63
+ #
64
+ # The 'object_type' passed as parameter is the top level object in object
65
+ # dependency.
66
+ # each config data are sorted by object dependencies and additionnal options
67
+ # defined in the application defaults.yaml at:
68
+ # /:section/<section name>/<data>/ See lib/core/code_model.rb
69
+ #
70
+ # setup will ask only data which are configured with :account => true
71
+ # /:section/<section name>/<data>/:account => true
72
+ #
73
+ # Additional config data can added to the list thanks to:
74
+ # /:setup/:ask_step/*:add/*
75
+ #
76
+ # Commonly, each data can define the following options:
77
+ # - :account: Optional. default: False
78
+ # => setup will ask the data only if :account is true
79
+ # - :desc: Required if :account is true. String. default: nil
80
+ # => Description
81
+ # - :explanation: |- Print a multiline explanation before asking the data
82
+ # ERB template enable. To get config data,
83
+ # type <%= config[...] %>
84
+ # - :ask_sort: Number sort position.
85
+ # - :after: Name of the previous <Data> to ask before the
86
+ # current one.
87
+ # - :depends_on: Additional data dependency.
88
+ # - :default_value: Default value at setup time.
89
+ # - :validate: Regular expression to validate end user input
90
+ # during setup.
91
+ # - :list_values: Additional options to get a list of possible values.
92
+ #
93
+ # For details or more options, see core_model.rb
94
+ #
95
+ # Setup is based on a config object which requires to have at least
96
+ # following functions:
97
+ # - value = get(key, default)
98
+ # - set(key, value)
99
+ # You can create you own config class, derived from Lorj::Config.
100
+ #
101
+ # When setup has done to ask data to the user, the config object is updated.
102
+ # It is up to you and your application to decide what you want to do with
103
+ # those data.
104
+ # Usually, if your application uses setup to setup an account settings
105
+ # Lorj::Account or some local application defaults Lorj::Config, you may
106
+ # want to save them to a configuration file.
107
+ # If you are using Lorj::Account, use function ac_save
108
+ # If you are using Lorj::Config, use function config_save
109
+ #
110
+ # * *Args* :
111
+ # - +ObjectType+ : Top object type to ask.
112
+ # - +sAccountName+ : Optional. Account Name to load if you are using a
113
+ # Lorj::Account Object.
114
+ #
115
+ # * *Returns* :
116
+ # - nothing.
117
+ #
118
+ # * *Raises* :
119
+ #
120
+ def process_setup(sObjectType, sAccountName = nil)
121
+ unless PrcLib.model.meta_obj.rh_exist?(sObjectType)
122
+ runtime_fail "Setup: '%s' not a valid object type."
123
+ end
124
+
125
+ setup_steps = _setup_load
126
+
127
+ @config.ac_load(sAccountName) if sAccountName
128
+
129
+ Lorj.debug(2, "Setup is identifying account data to ask for '%s'",
130
+ sObjectType)
131
+ # Loop in dependencies to get list of data object to setup
132
+ _setup_identify(sObjectType, setup_steps)
133
+
134
+ Lorj.debug(2, 'Setup check if needs to add unrelated data in the process')
135
+ _setup_check_additional(setup_steps)
136
+
137
+ Lorj.debug(2, "Setup will ask for :\n %s", setup_steps.to_yaml)
138
+
139
+ _setup_ask(setup_steps)
140
+ PrcLib.info("Configuring account : '#{config[:account_name]}',"\
141
+ " provider '#{config[:provider_name]}'")
142
+ end
143
+
144
+ # Internal function to insert the data after several data to ask.
145
+ #
146
+ # * *Args* :
147
+ # - data_to_check : setup data structure to update.
148
+ # - data_to_add : data to add
149
+ # - step : current step analyzed.
150
+ # - order_index : last order index of the current step analyzed.
151
+ #
152
+ # * *Returns*:
153
+ #
154
+ # * *Raises* :
155
+ #
156
+ def _setup_data_insert(setup_steps, data_to_add, step, order_index)
157
+ level_index = 0
158
+
159
+ _setup_data_after(data_to_add).each do |sAfterKey |
160
+ setup_steps.each_index do |iStepToCheck|
161
+ order_array = setup_steps[iStepToCheck][:order]
162
+
163
+ order_array.each_index do | iLevelToCheck |
164
+ data_to_ask = order_array[iLevelToCheck]
165
+ order_to_check = data_to_ask.index(sAfterKey)
166
+
167
+ next if order_to_check.nil?
168
+
169
+ step = iStepToCheck if iStepToCheck > step
170
+ level_index = iLevelToCheck if iLevelToCheck > level_index
171
+ order_index = order_to_check + 1 if order_to_check + 1 > order_index
172
+ break
173
+ end
174
+ end
175
+ end
176
+
177
+ setup_steps[step][:order][level_index].insert(order_index, data_to_add)
178
+ Lorj.debug(3, "S%s/L%s/O%s: '%s' added in setup list at position.",
179
+ step, level_index, order_index, data_to_add)
180
+ end
181
+
182
+ # Internal function to get :after list of data to ask.
183
+ #
184
+ # * *Args* :
185
+ # - data_to_check : setup data structure to update.
186
+ #
187
+ # * *Returns*:
188
+ # - Array : List of datas which requires to be ask before.
189
+ # Empty if not defined.
190
+ #
191
+ # * *Raises* :
192
+ #
193
+ def _setup_data_after(data_to_check)
194
+ meta = _get_meta_data(data_to_check)
195
+ return [] unless meta.rh_exist?(:after)
196
+
197
+ datas_after = meta[:after]
198
+ datas_after = [datas_after] unless datas_after.is_a?(Array)
199
+ datas_after
200
+ end
201
+
202
+ # check if a config data is already listed in the setup list at a specific
203
+ # step.
204
+ #
205
+ # * *Args* :
206
+ # - +order_array+ : Array of data classified per level/order
207
+ # - +data_to_check+ : data to check
208
+ def _setup_attr_already_added?(order_array, data_to_check)
209
+ order_array.each_index do | order_index |
210
+ attributes = order_array[order_index]
211
+ return true unless attributes.index(data_to_check).nil?
212
+ end
213
+ end
214
+
215
+ # Add the attribute parameter to setup list
216
+ # at the right position, determined by it dependencies.
217
+ #
218
+ # The attribute can be added only if :account is true. Data set in
219
+ # the application defaults.yaml:
220
+ # :sections/<Section>/<Attribute>/:account: true
221
+ #
222
+ # Attributes dependency is first loaded by the lorj object model
223
+ # Each attributes can add more dependency thanks to the application
224
+ # defaults.yaml:
225
+ # :sections/<Section>/<Attribute>/:depends_on (Array of attributes)
226
+ #
227
+ # The attribute step can be set from defaults.yaml as well:
228
+ # :sections/<Section>/<Attribute>/:ask_step (FixNum)
229
+ #
230
+ # The attribute can be asked at a determined index, set in
231
+ # the application defaults.yaml:
232
+ # :sections/<Section>/<Attribute>/:ask_sort: (FixNum)
233
+ #
234
+ # parameters :
235
+ # - +setup_steps+ : setup steps
236
+ # - +attr_name+ : Attribute to add
237
+ def _setup_obj_param_is_data(setup_steps, inspected_objects, attr_name)
238
+ if inspected_objects.include?(attr_name)
239
+ Lorj.debug(2, "#{attr_name} is already asked. Ignored.")
240
+ return false
241
+ end
242
+
243
+ meta = _get_meta_data(attr_name)
244
+ return false unless meta.is_a?(Hash)
245
+
246
+ ask_step = 0
247
+ ask_step = meta[:ask_step] if meta[:ask_step].is_a?(Fixnum)
248
+
249
+ Lorj.debug(3, "#{attr_name} is part of setup step #{ask_step}")
250
+ order_array = setup_steps[ask_step][:order]
251
+
252
+ unless meta[:account].is_a?(TrueClass)
253
+ Lorj.debug(2, "'%s' used by '%s' won't be asked during setup."\
254
+ ' :account = true not set.', attr_name, object_type)
255
+ return false
256
+ end
257
+
258
+ level_index = _setup_level_index(order_array, attr_name,
259
+ meta[:depends_on])
260
+
261
+ return true if order_array[level_index].include?(attr_name)
262
+
263
+ level = _setup_attr_add(order_array[level_index], attr_name, meta,
264
+ level_index)
265
+ Lorj.debug(3, "S%s/L%s/%s: '%s' added in setup list. ",
266
+ ask_step, level, order_index, attr_name)
267
+
268
+ true
269
+ end
270
+
271
+ # Function to identify level index for an attribute.
272
+ #
273
+ # parameters:
274
+ # - +order_array+ : array of levels of attributes ordered.
275
+ # - +attr_name+ : attribute name
276
+ # - +depends_on+ : Dependendy Array.
277
+ #
278
+ # return:
279
+ # - level_index to use.
280
+ def _setup_level_index(order_array, attr_name, depends_on)
281
+ if !depends_on.is_a?(Array)
282
+ PrcLib.warning("'%s' depends_on definition have to be"\
283
+ ' an array.',
284
+ attr_name) unless depends_on.nil?
285
+ 0
286
+ else
287
+ _setup_find_dep_level(order_array, meta[:depends_on])
288
+ end
289
+ end
290
+
291
+ # Function to add an attribute to the level layer of the setup array .
292
+ #
293
+ # parameters:
294
+ # - +level_array+ : array of attributes ordered.
295
+ # - +attr_name+ : attribute name
296
+ # - +order_index+ : order index where to insert the attribute.
297
+ #
298
+ def _setup_attr_add(level_array, attr_name, meta, level_index)
299
+ if meta[:ask_sort].is_a?(Fixnum)
300
+ order_index = meta[:ask_sort]
301
+ _setup_attr_add_at(level_array, attr_name, order_index)
302
+ Lorj.debug(3, "S%s/L%s/O%s: '%s' added in setup list. ",
303
+ ask_step, level_index, order_index, attr_name)
304
+ "O#{level_index}"
305
+ else
306
+ level_array << attr_name
307
+ Lorj.debug(3, "S%s/L%s/Last: '%s' added in setup list.",
308
+ ask_step, level_index, attr_name)
309
+ 'Last'
310
+ end
311
+ end
312
+
313
+ # Function to insert an attribute at a specific order.
314
+ # It will shift other attributes if needed.
315
+ #
316
+ # parameters:
317
+ # - +level_array+ : array of attributes ordered.
318
+ # - +attr_name+ : attribute name
319
+ # - +order_index+ : order index where to insert the attribute.
320
+ #
321
+ def _setup_attr_add_at(level_array, attr_name, order_index)
322
+ if level_array[order_index].nil?
323
+ level_array[order_index] = attr_name
324
+ else
325
+ level_array.insert(order_index, attr_name)
326
+ end
327
+ end
328
+
329
+ # Search for the lowest step to ask an attribute, thanks to dependencies.
330
+ #
331
+ # parameters:
332
+ # - +order_array+ : Array of attributes, at 2 dimensions [step then order]
333
+ # - +attr_dep+ : Array of attributes/objects needed before this
334
+ # attribute.
335
+ #
336
+ # returns:
337
+ # - the lowest step index where the attribute can be added.
338
+ def _setup_find_dep_level(order_array, attr_dep)
339
+ level_index = 0
340
+
341
+ attr_dep.each do |depend_key|
342
+ order_array.each_index do |iCurLevel|
343
+ if order_array[iCurLevel].include?(depend_key)
344
+ level_index = [level_index, iCurLevel + 1].max
345
+ end
346
+ end
347
+ order_array[level_index] = [] if order_array[level_index].nil?
348
+ end
349
+
350
+ level_index
351
+ end
352
+ end
353
+ end
@@ -0,0 +1,241 @@
1
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'highline/import'
16
+
17
+ # Module Lorj which contains several classes.
18
+ #
19
+ # Those classes describes :
20
+ # - processes (BaseProcess) : How to create/delete/edit/query object.
21
+ # - controler (BaseControler) : If a provider is defined, define how will do
22
+ # object creation/etc...
23
+ # - definition(BaseDefinition): Functions to declare objects, query/data mapping
24
+ # and setup
25
+ # this task to make it to work.
26
+ module Lorj
27
+ # Adding process core functions.
28
+ class BaseDefinition
29
+ # Internal setup function to ask to the end user.
30
+ # It execute post-process if defined by:
31
+ # /:section/<section name>/<data>/:post_step_function
32
+ #
33
+ # if post-process returns false, the user is requested to re-enter a
34
+ # new value
35
+ #
36
+ # * *Args* :
37
+ # - +desc+ : Data description
38
+ # - +data+ : Data to ask.
39
+ # - +options+: list and validation options
40
+ #
41
+ # * *Returns*:
42
+ # - value : value entered by the end user.
43
+ #
44
+ # * *Raises* :
45
+ #
46
+ def _setup_ask_data(desc, data, options)
47
+ loop do
48
+ if options[:list_values].nil?
49
+ value = _setup_ask_data_from_keyboard(desc, data, options)
50
+ else
51
+ value = _setup_ask_data_from_list(data, options[:list_values],
52
+ desc, options)
53
+ end
54
+
55
+ @config.set(data, value)
56
+
57
+ break if options[:post_step_function].nil?
58
+
59
+ proc = options[:post_step_function]
60
+ result = @process.method(proc).call
61
+
62
+ PrcLib.debug("Warning: '%s' did not return any boolean"\
63
+ ' value. Ignored', proc) unless result.boolean?
64
+
65
+ break unless result.is_a?(FalseClass)
66
+ end
67
+ end
68
+
69
+ # Internal setup function to ask to the end user from a list.
70
+ #
71
+ # * *Args* :
72
+ # - +obj_to_load+ : Object to get list from.
73
+ # - +list_options+: list and validation options
74
+ #
75
+ # * *Returns*:
76
+ # - Hash : list of possible values and default.
77
+ # :default_value : Value pre-selected.
78
+ # :list : list of possible values
79
+ #
80
+ # * *Raises* :
81
+ #
82
+ def _setup_choose_list_process(obj_to_load, list_options)
83
+ result = { :list => [], :default_value => nil }
84
+ case list_options[:query_type]
85
+ when :controller_call
86
+ result = _setup_list_from_controller_call(obj_to_load, list_options)
87
+ when :query_call
88
+ result = _setup_list_from_query_call(obj_to_load, list_options)
89
+ when :process_call
90
+ result = _setup_list_from_process_call(obj_to_load, list_options)
91
+ else
92
+ runtime_fail "'%s' invalid. %s/list_values/values_type supports '%s'.",
93
+ list_options[:values_type], data, [:provider_function]
94
+ end
95
+ result
96
+ end
97
+
98
+ # Internal setup function to ask to the end user from a list.
99
+ #
100
+ # * *Args* :
101
+ # - +data+ : Data to ask.
102
+ # - +list_options+: list and validation options
103
+ # - +desc+ : Data description
104
+ # - +options+ : Used when user have to enter a string instead of
105
+ # selecting from a list.
106
+ #
107
+ # * *Returns*:
108
+ # - value : value entered by the end user.
109
+ #
110
+ # * *Raises* :
111
+ #
112
+ def _setup_ask_data_from_list(data, list_options, desc, options)
113
+ obj_to_load = list_options[:object]
114
+
115
+ result = _setup_choose_list_process(obj_to_load, list_options)
116
+
117
+ list = result[:list]
118
+
119
+ is_strict_list = (list_options[:validate] == :list_strict)
120
+
121
+ if list.nil?
122
+ list = []
123
+
124
+ if is_strict_list
125
+ PrcLib.fatal(1, "%s requires a value from the '%s' query which is "\
126
+ 'empty.', data, obj_to_load)
127
+ else
128
+ list << 'Not in this list'
129
+ end
130
+ end
131
+
132
+ value = _setup_choose_data_from_list(data, desc, list, options)
133
+
134
+ if !is_strict_list && value == 'Not in this list'
135
+ value = _setup_ask_data_from_keyboard(desc, data, options,
136
+ result[:default_value])
137
+ end
138
+ value
139
+ end
140
+
141
+ # Internal setup function to present the list to the user and ask to choose.
142
+ #
143
+ # * *Args* :
144
+ # - +data+ : Data to ask.
145
+ # - +desc+ : Data description
146
+ # - +list+ : list of values to choose
147
+ # - +options+ : Used when user have to enter a string instead of
148
+ # selecting from a list.
149
+ #
150
+ # * *Returns*:
151
+ # - value : value entered by the end user.
152
+ #
153
+ # * *Raises* :
154
+ #
155
+ def _setup_choose_data_from_list(data, desc, list, options)
156
+ default = @config.get(data, options[:default_value])
157
+
158
+ say_msg = format("Select '%s' from the list:", desc)
159
+ say_msg += format(' |%s|', default) unless default.nil?
160
+ say(say_msg)
161
+ value = choose do | q |
162
+ q.choices(*list)
163
+ q.default = default if default
164
+ end
165
+ value
166
+ end
167
+
168
+ # Internal setup function to ask to the end user.
169
+ #
170
+ # * *Args* :
171
+ # - +desc+ : Data description
172
+ # - +data+ : Data to ask.
173
+ # - +options+: list and validation options
174
+ #
175
+ # * *Returns*:
176
+ # - value : value entered by the end user.
177
+ #
178
+ # * *Raises* :
179
+ #
180
+ def _setup_ask_data_from_keyboard(desc, data, options, default = nil)
181
+ valid_regex = nil
182
+ valid_regex = options[:validate] unless options[:validate].nil?
183
+
184
+ is_required = (options[:required] == true)
185
+ is_encrypted = options[:encrypted]
186
+
187
+ default = options[:default_value] if default.nil?
188
+ default = @config.get(data, default)
189
+
190
+ validate_proc = options[:validate_function]
191
+ proc_ask = options[:ask_function]
192
+
193
+ if proc_ask.nil?
194
+ proc_method = _ask
195
+ else
196
+ proc_method = @process.method(proc_ask)
197
+ end
198
+
199
+ loop do
200
+ value = proc_method.call(desc, default, valid_regex,
201
+ is_encrypted, is_required)
202
+ break if validate_proc.nil?
203
+
204
+ validate_method = @process.method(validate_proc)
205
+ break if validate_method.call(value)
206
+ end
207
+ value
208
+ end
209
+
210
+ # internal runtime function for process call
211
+ # Ask function executed by setup
212
+ #
213
+ # *parameters*:
214
+ # - +sDesc+ : data description
215
+ # - +default+ : default value
216
+ # - +rValidate+ : RegEx to validate the end user input.
217
+ # - +bEncrypted+ : Encrypt data
218
+ # - +bRequired+ : true if a value is required.
219
+ #
220
+ # *return*:
221
+ # - value : value or encrypted value.
222
+ #
223
+ # *raise*:
224
+ #
225
+ def _ask(sDesc, default, rValidate, bEncrypted, bRequired)
226
+ loop do
227
+ if bEncrypted
228
+ value = _ask_encrypted(sDesc, default)
229
+ else
230
+ value = ask(format('Enter %s:[%s]', sDesc, default)) do |q|
231
+ q.default = default unless default.nil?
232
+ q.validate = rValidate unless rValidate.nil?
233
+ end
234
+ end
235
+ break unless bRequired && value == ''
236
+ say ANSI.bold('This information is required!')
237
+ end
238
+ value.to_s
239
+ end
240
+ end
241
+ end