opensecret 0.0.913 → 0.0.941

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +3 -0
  3. data/README.md +129 -19
  4. data/Rakefile +0 -9
  5. data/bin/opensecret +1 -1
  6. data/lib/{opensecret/plugins.io/cipher/crypto.rb → crypto/amalgam.rb} +6 -8
  7. data/lib/crypto/collect.rb +139 -0
  8. data/lib/crypto/engineer.rb +201 -0
  9. data/lib/crypto/verify.rb +33 -0
  10. data/lib/extension/array.rb +133 -0
  11. data/lib/{opensecret/additions → extension}/dir.rb +0 -0
  12. data/lib/extension/file.rb +56 -0
  13. data/lib/extension/hash.rb +33 -0
  14. data/lib/extension/string.rb +349 -0
  15. data/lib/factbase/facts.opensecret.io.ini +28 -0
  16. data/lib/logging/gem.logging.rb +133 -0
  17. data/lib/opensecret.rb +102 -45
  18. data/lib/opensecret/executors/crypt.keys/crypt.keys.ini +0 -53
  19. data/lib/session/{session.rb → attributes.rb} +60 -5
  20. data/lib/session/exceptions.rb +53 -0
  21. data/lib/session/fact.finder.rb +684 -0
  22. data/lib/session/user.home.rb +49 -0
  23. data/lib/usecase/usecase.rb +245 -0
  24. data/lib/usecase/usecases/init.rb +190 -0
  25. data/lib/usecase/usecases/on.rb +33 -0
  26. data/lib/usecase/usecases/safe.rb +95 -0
  27. data/lib/version.rb +1 -1
  28. metadata +22 -17
  29. data/lib/opensecret/additions/array.rb +0 -117
  30. data/lib/opensecret/additions/string.rb +0 -312
  31. data/lib/opensecret/commons/eco.cmdline.rb +0 -446
  32. data/lib/opensecret/eco.do.rb +0 -46
  33. data/lib/opensecret/plugins.io/error/eco.exceptions.rb +0 -24
  34. data/lib/opensecret/plugins.io/facts/fact.chars.rb +0 -66
  35. data/lib/opensecret/plugins.io/facts/fact.factor.rb +0 -156
  36. data/lib/opensecret/plugins.io/facts/fact.locator.rb +0 -105
  37. data/lib/opensecret/plugins.io/facts/fact.reader.rb +0 -137
  38. data/lib/opensecret/plugins.io/facts/fact.tree.rb +0 -661
  39. data/lib/opensecret/plugins.io/logs/log.object.rb +0 -89
  40. data/lib/opensecret/plugins.io/logs/logging.rb +0 -203
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSession
4
+
5
+ # This class is the parent to all opensession errors
6
+ # that originate from the command line.
7
+ #
8
+ # All opensession cli originating errors are about
9
+ #
10
+ # - a problem with the input or
11
+ # - a problem with the current state or
12
+ # - a predictable future problem
13
+ class OpenSessionError < StandardError
14
+
15
+
16
+ # Initialize the error and provide a culprit
17
+ # object which will be to-stringed and given
18
+ # out as evidence (look at this)!
19
+ #
20
+ # This method will take care of loggin the error.
21
+ #
22
+ # @param message [String] human readable error message
23
+ # @param culprit [Object] object that is either pertinent, a culprit or culpable
24
+ def initialize message, culprit
25
+
26
+ super(message)
27
+
28
+ @the_culprit = culprit
29
+
30
+ log.info(x) { "An [Error] Occured => #{message}" }
31
+ log.info(x) { "Object of Interest => #{culprit.to_s}" } unless culprit.nil?
32
+ log.info(x) { "Class Name Culprit => #{culprit.class.name}" }
33
+ log.info(x) { "Error Message From => #{self.class.name}" }
34
+ e.backtrace.to_s.log_lines
35
+
36
+ end
37
+
38
+
39
+ # This method gives interested parties the object that
40
+ # is at the centre of the exception. This object is either
41
+ # very pertinent, culpable or at the very least, interesting.
42
+ #
43
+ # @return [String] string representation of culpable object
44
+ def culprit
45
+ return "No culprit identified." if @the_culprit.nil?
46
+ return @the_culprit.to_s
47
+ end
48
+
49
+
50
+ end
51
+
52
+
53
+ end
@@ -0,0 +1,684 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module OpenSession
4
+
5
+ require "pp"
6
+
7
+ # --
8
+ # -- -----------------
9
+ # -- Fact Production
10
+ # -- -----------------
11
+ # --
12
+ # -- The fact tree is tasked with fact production
13
+ # -- (population). Fact production is done by [consuming]
14
+ # --
15
+ # -- [1] - simple string, number of boolean facts
16
+ # -- [2] - facts already produced
17
+ # -- [3] - identity facts from command line and environment
18
+ # -- [4] - software (behaviour) that derives facts
19
+ # -- [5] - inherited (extended) facts from (OO) parents
20
+ # --
21
+ # --
22
+ # --
23
+ # -- -----------------------------------------
24
+ # -- The 4 Universal (DevOps) Creation Facts
25
+ # -- -----------------------------------------
26
+ # --
27
+ # -- No matter the (DevOps) eco-system being fabricated, these four
28
+ # -- facts prevail and stand out.
29
+ # --
30
+ # -- Every time a DevOps [eco-system] is created, cloned, or recovered,
31
+ # -- a small cluster of core facts endure to define the instance and act
32
+ # -- as the identification basis of all new eco-system resources.
33
+ # --
34
+ # -- The 4 facts underpinning eco-system creation are
35
+ # --
36
+ # -- [1] - [what] is being built
37
+ # -- [2] - [when] did the building begin
38
+ # -- [3] - [who] instigated it (and from)
39
+ # -- [4] - [which] workstation.
40
+ # --
41
+ # -- ---------------------------------------
42
+ # -- DevOps 4 Creational [Instance] Facts
43
+ # -- ---------------------------------------
44
+ # --
45
+ # -- The core instance identities used and reused time and again relate to
46
+ # --
47
+ # -- [1] - plugin (eg) wordpress.hub or jenkins.hub
48
+ # -- [2] - time (eg) 18036.0952.065
49
+ # -- [3] - user (eg) peterpan
50
+ # -- [4] - workstation (eg) laptop_susie or hp_desktop
51
+ # --
52
+ # --
53
+ class FactFind
54
+ include Singleton
55
+
56
+ @@eval_prefix = "rb>>"
57
+ attr_reader :i, :f
58
+
59
+ # --
60
+ # -- Initialize the internal fact database
61
+ # -- which is exposed for fact consumption
62
+ # -- via
63
+ # --
64
+ # -- @i => [identity] facts (1D)
65
+ # -- @n => (reserved perhaps 4 nested facts)
66
+ # -- @f => [file facts] database (2D)
67
+ # -- @a => (reserved)
68
+ # -- @c => coded consumtion (in software)
69
+ # -- @t => template placeholders (2D)
70
+ # -- @s => sibling (same category) facts (1D)
71
+ # --
72
+ def instantiate plugin_id
73
+
74
+ @i = { :plugin => plugin_id,
75
+ :time => Stamp.yyjjj_hhmm_sst,
76
+ :user => Home.usr,
77
+ :station => nil
78
+ }
79
+
80
+ @f = {}
81
+
82
+ @s = {}
83
+
84
+ @f.store symbol(plugin_id), {}
85
+ @p = @f[symbol(plugin_id)]
86
+
87
+
88
+ end
89
+
90
+
91
+
92
+ #--
93
+ #-- Set the main directory path.
94
+ #-- This method adds the parameter path to
95
+ #-- the identity map. After this method
96
+ #-- executes you will be able to access the
97
+ #-- directory with @i[:dir]
98
+ #--
99
+ def add_dir_to_identity key_directory
100
+ @i[:dir] = key_directory
101
+ end
102
+
103
+
104
+
105
+ # --
106
+ # --
107
+ # --
108
+ def assimilate_plugin_facts
109
+
110
+ plugin_fact_filepath = File.join @i[:src_dir], "#{@i[:plugin]}.ini"
111
+ log.info(x) { "Plugin Factfile => #{plugin_fact_filepath}" }
112
+ assimilate_ini_file plugin_fact_filepath
113
+
114
+ end
115
+
116
+
117
+ # --
118
+ # --
119
+ # --
120
+ def assimilate_general_facts
121
+
122
+ facts_folder = fact_path("published.facts")
123
+
124
+ factfiles_map = Files.in_folders( Array.new.push(facts_folder) )
125
+ factfiles_map.each do |file_name, folder_name|
126
+
127
+ log.info(x) {"Assimilating facts from => [#{file_name}]"}
128
+ factfile_path = File.join factfiles_map[file_name], file_name
129
+ log.info(x) {"Factfile location => [#{nickname factfile_path}]"}
130
+ assimilate_ini_file factfile_path
131
+
132
+ end
133
+
134
+ end
135
+
136
+
137
+ # Assimilate the gem's main factbase fact file into
138
+ # the structure that is exposed to outside classes
139
+ # as the instance variable @f (a 2D array type).
140
+ #
141
+ # The factfile to assimilate is always expected to
142
+ # exist in folder [ ../factbase ]
143
+ #
144
+ # The factfile name within the above folder is expected
145
+ # to be presented in the parameter.
146
+ #
147
+ # @param factfile_name [String] name of factfile to assimilate
148
+ def assimilate factfile_name
149
+
150
+ factfile_dir = File.join(File.dirname(File.expand_path(__FILE__)), "../factbase")
151
+ factfile_path = File.join factfile_dir, factfile_name
152
+
153
+ log.info(x) { "Assimilating factfile in folder => #{factfile_dir}" }
154
+ log.info(x) { "Assimilating factfile with name => #{factfile_name}" }
155
+
156
+ assimilate_ini_file factfile_path
157
+
158
+ end
159
+
160
+
161
+ # --
162
+ # -- Assimilate [[ hub-runtime.ini ]]
163
+ # -- This factfile builds upon the (fundamental) handful of
164
+ # -- identity facts. It derives the facts for
165
+ # --
166
+ # -- - the plugin instance folder
167
+ # -- - the instance stamp id keys
168
+ # --
169
+ # -- The instance fact file is not allowed to harbour any
170
+ # -- external dependencies.
171
+ # --
172
+ def assimilate_instance_facts
173
+
174
+ instance_facts_file = fact_path("hub-runtime.ini")
175
+ log.info(x) { "Path to instance facts file => #{instance_facts_file}" }
176
+ assimilate_ini_file instance_facts_file
177
+
178
+ end
179
+
180
+
181
+ # --
182
+ # -- -----------------------------------
183
+ # -- Finding the Workstation (Category)
184
+ # -- -----------------------------------
185
+ # --
186
+ # -- The known hosts facts file is parsed with each
187
+ # -- section [examined] by asking two (2) questions.
188
+ # --
189
+ # -- [1] - is [username] this workstation's username?
190
+ # -- [2] - does [hostnames] include this hostname?
191
+ # --
192
+ # -- The 1st section to answer [YES] to both questions
193
+ # -- is deemed as our workstation. Its symbol header is
194
+ # -- then used for assimilation - how?
195
+ # --
196
+ # -- ----------------------------------------
197
+ # -- Assimilating Workstation Specific Facts
198
+ # -- ----------------------------------------
199
+ # --
200
+ # -- We do NOT assimilate the whole file.
201
+ # -- We simply assimilate the [SECTION] of the file
202
+ # -- that is deemed to be OUR (this) workstation.
203
+ # --
204
+ # -- -------------------------------------------
205
+ # -- Dependency Constraints | Workstation Facts
206
+ # -- -------------------------------------------
207
+ # --
208
+ # -- (work)station facts can [only] depend on facts that
209
+ # -- have been declared in [[ hub-runtime.ini ]]. No
210
+ # -- other external fact dependencies are permitted.
211
+ # --
212
+ def identify_my_workstation
213
+
214
+ workstation_factfile_name = "known-hosts.ini"
215
+ log_begin_workstation_identification workstation_factfile_name
216
+ stations_factfile = fact_path workstation_factfile_name
217
+ log.info(x) { "Workstations Facts File (Path) => #{nickname stations_factfile}" }
218
+
219
+ our_user = Home.usr
220
+ our_host = NetDns.instance.host_name
221
+ log.info(x){ "Station Search For => #{our_user}@#{our_host}" }
222
+
223
+ workstations = IniFile.load stations_factfile
224
+ workstations.each_section do |station|
225
+
226
+ no_user = "Workstation [#{station}] has no [username] fact."
227
+ raise RuntimeError.new no_user unless workstations[station].has_key? "username"
228
+
229
+ has_hostnames = workstations[station].has_key? "hostnames"
230
+ no_hostnames = "[#{station}] not a workstation as no [hostnames] fact - Skip!"
231
+ log.warn(x) { no_hostnames } unless has_hostnames
232
+ next unless has_hostnames
233
+
234
+ this_user = evaluate(workstations[station]["username"])
235
+ these_hosts = evaluate(workstations[station]["hostnames"])
236
+ match = this_user.eql?(our_user) && these_hosts.include?(our_host)
237
+
238
+ log.info(x){ "[#{station}] with #{this_user}@#{these_hosts} - No!" } unless match
239
+ next unless match
240
+
241
+ log.info(x){ "[#{station}] with #{this_user}@#{these_hosts} - Matched!" }
242
+ dup_msg = "Duplicate or repeat match disallowed! #{@i[:station]} and #{station}"
243
+ raise RuntimeError.new dup_msg unless @i[:station].nil?
244
+
245
+ @i[:station] = station
246
+ @i[:workstation] = station.gsub(".", "_").to_sym
247
+
248
+ end
249
+
250
+ no_match_msg = "No workstation match made for [#{our_user}@#{our_host}]."
251
+ raise RuntimeError.new no_match_msg if @i[:station].nil?
252
+ log_end_workstation_identification workstation_factfile_name
253
+ LogObject.map @i
254
+
255
+ end
256
+
257
+
258
+ #--
259
+ #-- Knowing and setting @i[:workstation] to our workstation is key.
260
+ #-- This means that the other workstations can reference files in
261
+ #-- each others drives without knowing which workstation is being
262
+ #-- used (see ssh.keyfile for a ghost reference example).
263
+ #--
264
+ #-- Now we can proceed to assimilate the entire station facts file.
265
+ #--
266
+ def assimilate_station_facts
267
+
268
+ stations_factfile = fact_path "known-hosts.ini"
269
+ assimilate_ini_file stations_factfile
270
+
271
+ end
272
+
273
+
274
+ # --
275
+ # -- Get the path to a fact file or folder within the
276
+ # -- reusable facts source tree.
277
+ # --
278
+ # -- The base directory is acquired by dropping down
279
+ # -- three (3) directory levels from where this module
280
+ # -- is and then going into reusable.facts and finally
281
+ # -- appending the parameter path (file or folder).
282
+ # --
283
+ def fact_path fact_filename
284
+ fact_basedir = File.dirname( File.dirname( File.dirname( __FILE__ ) ) )
285
+ return File.join( File.join(fact_basedir,"reusable.facts"), fact_filename )
286
+ end
287
+
288
+
289
+ # --
290
+ # -- Call instantiate() before calling populate().
291
+ # --
292
+ # -- This method assimilates any and all fact files
293
+ # -- (recursively) found in two subdirectories
294
+ # --
295
+ # -- [1] - "reusable facts" and
296
+ # -- [2] - the [plugin] folder
297
+ # --
298
+ def self.populate
299
+
300
+ end
301
+
302
+
303
+ # -- -------------------------------------------------------------- -- #
304
+ # -- Eval and return result of parameter string if it is ruby code. -- #
305
+ # -- -------------------------------------------------------------- -- #
306
+ def evaluate string
307
+
308
+ # -----> @todo raise a FactError here
309
+
310
+ raise RuntimeError.new "Fact to Evaluate is Nil." if string.nil?
311
+ return string unless string.start_with? @@eval_prefix
312
+ return eval( string.gsub @@eval_prefix, "" )
313
+
314
+ end
315
+
316
+
317
+ # ----> -------------------------------------------------->
318
+ # ----> How to Write a Custom Error
319
+ # ----> -------------------------------------------------->
320
+ # ----> Add a custom data attributes to your exception
321
+ # ----> You can add custom data to your exception just like you'd do it in any other class. Let's add an attribute reader to our class and update the constructor.
322
+ # ----> class MyError < StandardError
323
+ # ----> attr_reader :thing
324
+ # ----> def initialize(msg="My default message", thing="apple")
325
+ # ----> @thing = thing
326
+ # ----> super(msg)
327
+ # ----> end
328
+ # ----> end
329
+ # ----> -------------------------------------------------->
330
+ # ----> Using the Custom Error Class
331
+ # ----> -------------------------------------------------->
332
+ # ----> begin
333
+ # ----> raise MyError.new("my message", "my thing")
334
+ # ----> rescue => e
335
+ # ----> puts e.thing # "my thing"
336
+ # ----> end
337
+ # ----> -------------------------------------------------->
338
+
339
+
340
+ # -- ---------------------------------------- -- #
341
+ # -- Add a fact to the main 2D fact database. -- #
342
+ # -- ---------------------------------------- -- #
343
+ def add_fact group_symbol, key_symbol, key_value
344
+
345
+ nil_error_text = "Neither fact coordinates nor value can be nil. [group]=> #{group_symbol} [key]=> #{key_symbol} [value]=> #{key_value}"
346
+ raise ArgumentError.new nil_error_text if group_symbol.nil? || key_symbol.nil? || key_value.nil?
347
+
348
+ if @f.has_key? group_symbol then
349
+
350
+ # --
351
+ # -- This isn't the first fact within this group
352
+ # -- so store the new fact key/value pair within
353
+ # -- the group's namespace.
354
+ # --
355
+ @f[group_symbol][key_symbol] = key_value
356
+
357
+ else
358
+
359
+ # --
360
+ # -- Create a new umbrella grouping against which
361
+ # -- the new key-value pairing will be inserted.
362
+ # --
363
+ @f.store group_symbol, { key_symbol => key_value }
364
+
365
+ end
366
+
367
+ # --
368
+ # -- The @s sibling hash is updated to reflect the
369
+ # -- key-value pairs within the current group. This
370
+ # -- allows @s to be used as shorthand within INI
371
+ # -- file fact definition statements.
372
+ # --
373
+ @s = @f[group_symbol]
374
+
375
+ end
376
+
377
+
378
+ # -- ------------------------------------------- -- #
379
+ # -- -- #
380
+ # -- Template -- #
381
+ # -- -- #
382
+ # -- The longest river in africa is without -- #
383
+ # -- doubt the @[africa|longest.river]. Now -- #
384
+ # -- @[south.america|most.spoken] is the -- #
385
+ # -- most common language in south america. -- #
386
+ # -- -- #
387
+ # -- The population of the americas -- #
388
+ # -- is @[americas|population] according to
389
+ # -- the Harvard 2015 census.
390
+ # -- -- #
391
+ # -- ------------------------------------------- -- #
392
+ # -- -- #
393
+ # -- Ruby Code -- #
394
+ # -- -- #
395
+ # -- double_north_america_pop = @f[:north_america][:population] * 2
396
+ # -- -- #
397
+ # -- ------------------------------------------- -- #
398
+ # -- Parameters -- #
399
+ # -- factory_facts : instantiated 2D hash -- #
400
+ # -- ini_filepath : path to factfile to read -- #
401
+ # -- -- #
402
+ # -- Dependencies and Assumptions -- #
403
+ # -- the [inifile] gem is installed -- #
404
+ # -- file exists at the ini_filepath -- #
405
+ # -- factory_facts are instantiated -- #
406
+ # -- identity facts like @i[:plugin] exist -- #
407
+ # -- ------------------------------------------- -- #
408
+ def assimilate_ini_file ini_filepath
409
+
410
+ fact_filename = File.basename ini_filepath
411
+ log_begin fact_filename
412
+
413
+ no_file = "No (ini) factfile found here => #{ini_filepath}"
414
+ raise ArgumentError.new no_file unless File.exists? ini_filepath
415
+
416
+ # --
417
+ # -- Use the inifile gem to parse and read the fact
418
+ # -- file contents into Ruby's map structures.
419
+ # --
420
+ begin
421
+
422
+ map_facts = IniFile.load ini_filepath
423
+ map_facts.each do | group_str, key_str, input_value |
424
+ assimilate_fact group_str, key_str, input_value
425
+ end
426
+
427
+ rescue Exception => e
428
+
429
+ log.fatal(x) { "## ############################ #################################" }
430
+ log.fatal(x) { "## Fact File Assimilation Error ---------------------------------" }
431
+ log.fatal(x) { "## ############################ #################################" }
432
+ log.fatal(x) { "## File => #{ini_filepath}" }
433
+ log.fatal(x) { "## Error => #{e.message}" }
434
+ log.fatal(x) { "## ############################ #################################" }
435
+ e.backtrace.log_lines
436
+ log.fatal(x) { "## ############################ #################################" }
437
+
438
+ raise e
439
+
440
+ end
441
+
442
+ log_end fact_filename
443
+
444
+ end
445
+
446
+
447
+
448
+ def assimilate_fact group_str, key_str, input_value
449
+
450
+ grp_symbol = group_str.gsub(".", "_").to_sym
451
+ key_symbol = key_str.gsub(".", "_").to_sym
452
+
453
+ raise ArgumentError, "Assimilating Fact [ #{group_str} ][ #{key_str} ] => Value is NIL" if input_value.nil?
454
+
455
+ fact_val = input_value.strip
456
+
457
+ begin
458
+
459
+ unless discard_fact?( group_str, key_str, fact_val )
460
+ eval_value = evaluate(get_fact_value(fact_val))
461
+ add_fact grp_symbol, get_key_symbol(key_str), eval_value
462
+ end
463
+
464
+ rescue Exception => e
465
+
466
+ log.fatal(x) { "## ##################### #################################" }
467
+ log.fatal(x) { "## Fact Evaluation Error ---------------------------------" }
468
+ log.fatal(x) { "## ##################### #################################" }
469
+ log.fatal(x) { "## Fact Family => #{group_str}" }
470
+ log.fatal(x) { "## Fact Key => #{key_str}" }
471
+ log.fatal(x) { "## Fact Stmt => #{fact_val}" }
472
+ log.fatal(x) { "## Fact Error => #{e.message}" }
473
+ log.fatal(x) { "## ##################### #################################" }
474
+ e.backtrace.log_lines
475
+
476
+ raise e
477
+
478
+ end
479
+
480
+ unless @f.has_key? grp_symbol then
481
+
482
+ log.debug(x){ "# -- ---------------------------------------------------------- #" }
483
+ log.debug(x){ "# -- the [#{group_str}] silo facts." }
484
+ log.debug(x){ "# -- ---------------------------------------------------------- #" }
485
+
486
+ end
487
+
488
+ id_keystring = "#{grp_symbol}#{key_symbol}".downcase
489
+ sensitive = id_keystring.includes_any? [ "secret", "password", "credential", "creds" ]
490
+ print_value = "****************"
491
+ print_value = eval_value unless sensitive
492
+
493
+ # -- -------------------------------------------------------- -- #
494
+ # -- Log the human readable (fixed-width) key and value pair. -- #
495
+ # -- -------------------------------------------------------- -- #
496
+ fw_key = sprintf '%-33s', "@f[:#{grp_symbol}][:#{key_symbol}]"
497
+ log.debug(x){ "#{fw_key} => #{print_value}" }
498
+
499
+ end
500
+
501
+
502
+ def discard_fact? group_str, key_str, input_value
503
+
504
+ is_if = key_str.strip.end_with? "(if)"
505
+ is_unless = key_str.strip.end_with?("(un)") || key_str.strip.end_with?("(unless)")
506
+ return false unless is_if || is_unless
507
+
508
+ two_parts = input_value.split( @@eval_prefix )
509
+ no_prefix = "Conditional must be followed by eval prefix => #{two_parts}"
510
+ raise RuntimeError.new no_pefix unless two_parts.length == 2
511
+
512
+ conditional_part = two_parts.first.strip
513
+ no_curlies_msg = "Wrap conditional in curly braces => #{conditional_part}"
514
+ is_wrapped = conditional_part.start_with?("{") && conditional_part.end_with?("}")
515
+ raise RuntimeError.new no_curlies_msg unless is_wrapped
516
+
517
+ conditional_stmt = conditional_part[1..-2].strip
518
+ log.info(x){ "Conditional Stmt => #{conditional_stmt}" }
519
+ conditional_val = evaluate( @@eval_prefix + conditional_stmt )
520
+ is_boolean = [true, false].include? conditional_val
521
+
522
+ boolean_msg = "=> #{conditional_stmt} <= evaluated to [#{conditional_val}] not boolean."
523
+ raise RuntimeError.new boolean_msg unless is_boolean
524
+
525
+ return false if is_if && conditional_val
526
+ return true if is_if && !conditional_val
527
+
528
+ return true if is_unless && conditional_val
529
+ return false if is_unless && !conditional_val
530
+
531
+ raise RuntimeError.new "Unreachable if[#{is_if}] unless[#{is_unless}] => #{conditional_val}"
532
+
533
+ end
534
+
535
+
536
+ #--
537
+ #-- Return the symbolic representation of the
538
+ #-- parameter key. Periods are replaced with
539
+ #-- underscores (as per the fact convention)
540
+ #-- before conversion to a symbol.
541
+ #--
542
+ #-- Nil is not handled.
543
+ #-- String is stripped beforehand just in case.
544
+ #--
545
+ def symbol from_string
546
+
547
+ return from_string.strip.gsub(".", "_").to_sym
548
+
549
+ end
550
+
551
+
552
+ #--
553
+ #-- Return the (key access) symbol that represents the
554
+ #-- plugin id plus a string given in the parameter.
555
+ #--
556
+ #-- ---------
557
+ #-- Example
558
+ #-- ---------
559
+ #--
560
+ #-- Plugin Id => ide.hub
561
+ #-- Append Str => host
562
+ #--
563
+ #-- equals
564
+ #--
565
+ #-- Key String => ide.hub.host
566
+ #-- Key Symbol => ide_hub_host
567
+ #--
568
+ #--
569
+ #-- So the symbol :ide_hub_host is returned.
570
+ #--
571
+ def plugin_symbol append_string
572
+
573
+ key_string = @i[:plugin] + "." + append_string.strip
574
+ return key_string.gsub(".", "_").to_sym
575
+
576
+ end
577
+
578
+
579
+ def get_key_symbol dirty_key_string
580
+
581
+ key_string = dirty_key_string.strip
582
+ split_string = "(unless)"
583
+ split_string = "(if)" if key_string.end_with? "(if)"
584
+ split_string = "(un)" if key_string.end_with? "(un)"
585
+
586
+ return key_string.split(split_string).first.gsub(".", "_").to_sym
587
+
588
+ end
589
+
590
+
591
+ def get_fact_value fact_value_string
592
+
593
+ is_conditional = fact_value_string.start_with?("{") && fact_value_string.include?( @@eval_prefix )
594
+ return fact_value_string unless is_conditional
595
+
596
+ return fact_value_string.rpartition( @@eval_prefix )[1..-1].join
597
+
598
+ end
599
+
600
+
601
+ def exists? fact_reference
602
+
603
+ log.info(x) { "Does Fact Exist? => #{fact_reference}" }
604
+ return false if fact_reference.nil?
605
+ return false if fact_reference.strip.length == 0
606
+ return true if fact_reference.strip.length > 0
607
+
608
+ end
609
+
610
+
611
+ # --
612
+ # -- dot => period (full stop)
613
+ # -- Deliver a "." period character
614
+ # --
615
+ def dot
616
+ return "."
617
+ end
618
+
619
+
620
+ # --
621
+ # -- colon => full colon character
622
+ # -- Delivers a ":" colon character
623
+ # --
624
+ def colon
625
+ return ":"
626
+ end
627
+
628
+
629
+ def log_begin_workstation_identification the_filename
630
+
631
+ log.info(x) { "- -" }
632
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
633
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
634
+ log.info(x) { "# -- [= BEGIN WORKSTATION IDENTIFICATION =] #{the_filename}" }
635
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
636
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
637
+
638
+ end
639
+
640
+
641
+ def log_end_workstation_identification the_filename
642
+
643
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
644
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
645
+ log.info(x) { "# -- [= END WORKSTATION IDENTIFICATION =] #{the_filename}" }
646
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
647
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
648
+ log.info(x) { "- -" }
649
+ log.info(x) { "- -" }
650
+ log.info(x) { "- -" }
651
+
652
+ end
653
+
654
+
655
+ def log_begin the_filename
656
+
657
+ log.info(x) { "- -" }
658
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
659
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
660
+ log.info(x) { "# -- [= BEGIN THE ASSIMILATION =] #{the_filename}" }
661
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
662
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
663
+
664
+ end
665
+
666
+
667
+ def log_end the_filename
668
+
669
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
670
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
671
+ log.info(x) { "# -- [= END ASSIMILATION =] #{the_filename}" }
672
+ log.info(x) { "# -- ------------------------------------------------- -- #" }
673
+ log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
674
+ log.info(x) { "- -" }
675
+ log.info(x) { "- -" }
676
+ log.info(x) { "- -" }
677
+
678
+ end
679
+
680
+
681
+ end
682
+
683
+
684
+ end