opensecret 0.0.2 → 0.0.4

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