opensecret 0.0.9925 → 0.0.9949

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +656 -40
  3. data/lib/configs/README.md +58 -0
  4. data/lib/extension/file.rb +67 -0
  5. data/lib/extension/string.rb +10 -0
  6. data/lib/factbase/facts.opensecret.io.ini +1 -0
  7. data/lib/interprete.rb +334 -61
  8. data/lib/keytools/PRODUCE_RAND_SEQ_USING_DEV_URANDOM.txt +0 -0
  9. data/lib/keytools/kdf.api.rb +9 -15
  10. data/lib/keytools/kdf.bcrypt.rb +69 -19
  11. data/lib/keytools/kdf.pbkdf2.rb +112 -23
  12. data/lib/keytools/key.api.rb +146 -36
  13. data/lib/keytools/key.db.rb +94 -29
  14. data/lib/keytools/key.id.rb +1 -1
  15. data/lib/keytools/key.ident.rb +243 -0
  16. data/lib/keytools/key.local.rb +62 -68
  17. data/lib/keytools/key.pass.rb +2 -2
  18. data/lib/keytools/key.rb +2 -28
  19. data/lib/modules/{cryptology.md → README.md} +0 -0
  20. data/lib/session/fact.finder.rb +65 -428
  21. data/lib/session/time.stamp.rb +1 -28
  22. data/lib/usecase/cmd.rb +127 -54
  23. data/lib/usecase/config/README.md +57 -0
  24. data/lib/usecase/docker/README.md +146 -0
  25. data/lib/usecase/docker/docker.rb +49 -0
  26. data/lib/usecase/edit/README.md +43 -0
  27. data/lib/usecase/edit/delete.rb +46 -0
  28. data/lib/usecase/export.rb +40 -0
  29. data/lib/usecase/files/README.md +37 -0
  30. data/lib/usecase/files/eject.rb +56 -0
  31. data/lib/usecase/files/file_me.rb +78 -0
  32. data/lib/usecase/files/read.rb +169 -0
  33. data/lib/usecase/files/write.rb +89 -0
  34. data/lib/usecase/goto.rb +57 -0
  35. data/lib/usecase/id.rb +1 -1
  36. data/lib/usecase/import.rb +13 -30
  37. data/lib/usecase/init.rb +2 -17
  38. data/lib/usecase/jenkins/README.md +146 -0
  39. data/lib/usecase/jenkins/crazy_ruby_post_attempt.OLD +234 -0
  40. data/lib/usecase/jenkins/jenkins.rb +208 -0
  41. data/lib/usecase/login.rb +6 -5
  42. data/lib/usecase/logout.rb +1 -3
  43. data/lib/usecase/open.rb +11 -66
  44. data/lib/usecase/print.rb +40 -0
  45. data/lib/usecase/put.rb +34 -156
  46. data/lib/usecase/set.rb +2 -4
  47. data/lib/usecase/show.rb +138 -0
  48. data/lib/usecase/terraform/README.md +91 -0
  49. data/lib/usecase/terraform/terraform.rb +121 -0
  50. data/lib/usecase/token.rb +4 -80
  51. data/lib/usecase/update/README.md +55 -0
  52. data/lib/usecase/update/rename.rb +180 -0
  53. data/lib/usecase/use.rb +1 -3
  54. data/lib/usecase/verse.rb +20 -0
  55. data/lib/usecase/view.rb +71 -0
  56. data/lib/usecase/vpn/README.md +150 -0
  57. data/lib/usecase/vpn/vpn.ini +31 -0
  58. data/lib/usecase/vpn/vpn.rb +54 -0
  59. data/lib/version.rb +1 -1
  60. data/opensecret.gemspec +3 -4
  61. metadata +34 -35
  62. data/.travis.yml +0 -5
  63. data/CODE_OF_CONDUCT.md +0 -74
  64. data/LICENSE.txt +0 -21
  65. data/bin/ops +0 -20
  66. data/lib/keytools/binary.map.rb +0 -294
  67. data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +0 -179
  68. data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +0 -190
  69. data/lib/keytools/doc.star.schema.strategy.txt +0 -77
  70. data/lib/keytools/doc.using.pbkdf2.kdf.ruby +0 -95
  71. data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +0 -266
  72. data/lib/keytools/key.mach.rb +0 -248
  73. data/lib/keytools/keydebug.txt +0 -295
  74. data/lib/modules/cryptology/open.bcrypt.rb +0 -170
  75. data/lib/usecase/read.rb +0 -89
  76. data/lib/usecase/safe.rb +0 -92
@@ -43,14 +43,14 @@ module OpenKey
43
43
  assert_min_size MINIMUM_PASSWORD_SIZE
44
44
 
45
45
  sleep(1)
46
- puts "\nEnter a Password : "
46
+ puts "Password:"
47
47
  first_secret = STDIN.noecho(&:gets).chomp
48
48
 
49
49
  assert_input_text_size first_secret.length, MINIMUM_PASSWORD_SIZE
50
50
  return first_secret unless prompt_twice
51
51
 
52
52
  sleep(1)
53
- puts "\nRe-enter the password : "
53
+ puts "Re-enter the password:"
54
54
  check_secret = STDIN.noecho(&:gets).chomp
55
55
 
56
56
  assert_same_size_text first_secret, check_secret
@@ -316,8 +316,8 @@ module OpenKey
316
316
  #
317
317
  # This method should only ever be called when this key has been derived
318
318
  # from either a (huge) <b>48 byte random source</b> or from a key derivation
319
- # function (KDF) such as BCrypt, SCrypt, PBKDF2 or a union from {KdfApi}
320
- # which delivers 512 bit (64 byte) key for reduction to 256 bits.
319
+ # function (KDF) such as BCrypt, SCrypt, PBKDF2 or a union from which the
320
+ # 512 bit (64 byte) key can be reduced to 256 bits.
321
321
  #
322
322
  # @return [String]
323
323
  # a binary string of thirty-two (32) eight (8) bit bytes which
@@ -407,24 +407,12 @@ module OpenKey
407
407
  calling_lineno = caller_locations(1,1).first.lineno
408
408
  caller_details = "#{calling_module} | #{calling_method} | (line #{calling_lineno})"
409
409
 
410
- log.info(x) { "### #####################################################################" }
411
- log.info(x) { "### Caller Details =>> =>> #{caller_details}" }
412
- log.info(x) { "### #####################################################################" }
413
- log.info(x) { "The BitStr Char representation of this key => #{to_s()}" }
414
- log.info(x) { "256bit Digest (Urlsafe Base64) of this key => #{Base64.urlsafe_encode64(to_aes_key())}" }
415
- log.info(x) { "The IncomingKey Base64 Char representation => #{key_to_encrypt.to_char64()}" }
416
- log.info(x) { "Random IV Used for the AESs Key Encryption => #{Base64.urlsafe_encode64(random_iv)}" }
417
-
418
410
  cipher_text = crypt_cipher.update( key_to_encrypt.to_char64 ) + crypt_cipher.final
419
- log.info(x) { "Cipher Text Produced after this Encryption => #{Base64.urlsafe_encode64(cipher_text)}" }
420
411
 
421
412
  binary_text = random_iv + cipher_text
422
413
  ones_zeroes = binary_text.unpack("B*")[0]
423
414
  ciphertxt64 = Key64.from_bits( ones_zeroes )
424
415
 
425
- log.info(x) { "Amalgam of Binary Random IV and Ciphertext => #{ciphertxt64}" }
426
- log.info(x) { "------------------------------------------------------------------------- >>>>>>" }
427
-
428
416
  size_msg = "Expected bit count is #{EXPECTED_CIPHER_BIT_LENGTH} not #{ones_zeroes.length}."
429
417
  raise RuntimeError, size_msg unless ones_zeroes.length == EXPECTED_CIPHER_BIT_LENGTH
430
418
 
@@ -468,18 +456,6 @@ module OpenKey
468
456
  # the size of the parameter ciphertext must be 128 base 64 characters.
469
457
  def do_decrypt_key ciphertext_to_decrypt
470
458
 
471
- calling_module = File.basename caller_locations(1,1).first.absolute_path, ".rb"
472
- calling_method = caller_locations(1,1).first.base_label
473
- calling_lineno = caller_locations(1,1).first.lineno
474
- caller_details = "#{calling_module} | #{calling_method} | (line #{calling_lineno})"
475
-
476
- log.info(x) { "### #####################################################################" }
477
- log.info(x) { "### Caller Details =>> =>> #{caller_details}" }
478
- log.info(x) { "### #####################################################################" }
479
- log.info(x) { "Amalgam of Binary Random IV and Ciphertext => #{ciphertext_to_decrypt}" }
480
- log.info(x) { "The Base64 Char representation of this key => #{to_s()}" }
481
- log.info(x) { "256bit Digest (Urlsafe Base64) of this key => #{Base64.urlsafe_encode64(to_aes_key())}" }
482
-
483
459
  bit_text = Key64.to_bits(ciphertext_to_decrypt)
484
460
  size_msg = "Expected bit count is #{EXPECTED_CIPHER_BIT_LENGTH} not #{bit_text.length}."
485
461
  raise RuntimeError, size_msg unless bit_text.length == EXPECTED_CIPHER_BIT_LENGTH
@@ -493,8 +469,6 @@ module OpenKey
493
469
  cipher_x.iv = rawbytes[ 0 .. ( RANDOM_IV_BYTE_COUNT - 1 ) ]
494
470
  key_chars_64 = cipher_x.update( rawbytes[ RANDOM_IV_BYTE_COUNT .. -1 ] ) + cipher_x.final
495
471
 
496
- log.info(x) { "The OutgoingKey Base64 Char representation => #{key_chars_64}" }
497
-
498
472
  return Key.from_char64( key_chars_64 )
499
473
 
500
474
  end
File without changes
@@ -1,21 +1,6 @@
1
1
  #!/usr/bin/ruby
2
2
 
3
- # opensession contains basic behaviour for managing a client only
4
- # (serverless) session. Configuration directives are read and written
5
- # from an INI off the home directory that is created when the session
6
- # is first initiated.
7
- #
8
- # The session is expected to be formally closed down and that is
9
- # reflected by explicitly deleting the configuration file. If this
10
- # "session over" command is not issued a reasonable time limit is
11
- # then invoked when the next session command is issued.
12
- #
13
- # This "session awakening" wipes the slate clean and starts afresh
14
- # with regard to the two dimensional array of configuration directive
15
- # pointers.
16
- module OpenSession
17
-
18
- require "pp"
3
+ module OpenSecret
19
4
 
20
5
  # --
21
6
  # -- -----------------
@@ -64,85 +49,23 @@ module OpenSession
64
49
  # --
65
50
  # --
66
51
  class FactFind
67
- include Singleton
68
52
 
69
53
  @@eval_prefix = "rb>>"
70
- attr_reader :i, :f
71
-
72
- # --
73
- # -- Initialize the internal fact database
74
- # -- which is exposed for fact consumption
75
- # -- via
76
- # --
77
- # -- @i => [identity] facts (1D)
78
- # -- @n => (reserved perhaps 4 nested facts)
79
- # -- @f => [file facts] database (2D)
80
- # -- @a => (reserved)
81
- # -- @c => coded consumtion (in software)
82
- # -- @t => template placeholders (2D)
83
- # -- @s => sibling (same category) facts (1D)
84
- # --
85
- def instantiate plugin_id
86
-
87
- @i = { :plugin => plugin_id,
88
- :time => Stamp.yyjjj_hhmm_sst,
89
- :user => Home.usr,
90
- :station => nil
91
- }
92
54
 
93
- @f = {}
94
-
95
- @s = {}
96
-
97
- @f.store symbol(plugin_id), {}
98
- @p = @f[symbol(plugin_id)]
99
-
100
-
101
- end
102
-
103
-
104
-
105
- #--
106
- #-- Set the main directory path.
107
- #-- This method adds the parameter path to
108
- #-- the identity map. After this method
109
- #-- executes you will be able to access the
110
- #-- directory with @i[:dir]
111
- #--
112
- def add_dir_to_identity key_directory
113
- @i[:dir] = key_directory
114
- end
115
-
116
-
117
-
118
- # --
119
- # --
120
- # --
121
- def assimilate_plugin_facts
122
-
123
- plugin_fact_filepath = File.join @i[:src_dir], "#{@i[:plugin]}.ini"
124
- log.info(x) { "Plugin Factfile => #{plugin_fact_filepath}" }
125
- assimilate_ini_file plugin_fact_filepath
55
+ # The fact tree values can be referenced using the @f
56
+ # specifier with a 2 dimensional key.
57
+ attr_reader :f
126
58
 
127
- end
128
-
129
-
130
- # --
131
- # --
132
- # --
133
- def assimilate_general_facts
134
59
 
135
- facts_folder = fact_path("published.facts")
60
+ # This method constructs the FactFind object and tree database
61
+ # and initializers the root fact container structures.
62
+ def initialize
136
63
 
137
- factfiles_map = Files.in_folders( Array.new.push(facts_folder) )
138
- factfiles_map.each do |file_name, folder_name|
139
-
140
- log.info(x) {"Assimilating facts from => [#{file_name}]"}
141
- factfile_path = File.join factfiles_map[file_name], file_name
142
- log.info(x) {"Factfile location => [#{nickname factfile_path}]"}
143
- assimilate_ini_file factfile_path
64
+ @f = {}
65
+ @s = {}
144
66
 
145
- end
67
+ # ---> @f.store symbol(plugin_id), {}
68
+ # ---> @p = @f[symbol(plugin_id)]
146
69
 
147
70
  end
148
71
 
@@ -171,162 +94,6 @@ module OpenSession
171
94
  end
172
95
 
173
96
 
174
- # --
175
- # -- Assimilate [[ hub-runtime.ini ]]
176
- # -- This factfile builds upon the (fundamental) handful of
177
- # -- identity facts. It derives the facts for
178
- # --
179
- # -- - the plugin instance folder
180
- # -- - the instance stamp id keys
181
- # --
182
- # -- The instance fact file is not allowed to harbour any
183
- # -- external dependencies.
184
- # --
185
- def assimilate_instance_facts
186
-
187
- instance_facts_file = fact_path("hub-runtime.ini")
188
- log.info(x) { "Path to instance facts file => #{instance_facts_file}" }
189
- assimilate_ini_file instance_facts_file
190
-
191
- end
192
-
193
-
194
- # --
195
- # -- -----------------------------------
196
- # -- Finding the Workstation (Category)
197
- # -- -----------------------------------
198
- # --
199
- # -- The known hosts facts file is parsed with each
200
- # -- section [examined] by asking two (2) questions.
201
- # --
202
- # -- [1] - is [username] this workstation's username?
203
- # -- [2] - does [hostnames] include this hostname?
204
- # --
205
- # -- The 1st section to answer [YES] to both questions
206
- # -- is deemed as our workstation. Its symbol header is
207
- # -- then used for assimilation - how?
208
- # --
209
- # -- ----------------------------------------
210
- # -- Assimilating Workstation Specific Facts
211
- # -- ----------------------------------------
212
- # --
213
- # -- We do NOT assimilate the whole file.
214
- # -- We simply assimilate the [SECTION] of the file
215
- # -- that is deemed to be OUR (this) workstation.
216
- # --
217
- # -- -------------------------------------------
218
- # -- Dependency Constraints | Workstation Facts
219
- # -- -------------------------------------------
220
- # --
221
- # -- (work)station facts can [only] depend on facts that
222
- # -- have been declared in [[ hub-runtime.ini ]]. No
223
- # -- other external fact dependencies are permitted.
224
- # --
225
- def identify_my_workstation
226
-
227
- workstation_factfile_name = "known-hosts.ini"
228
- log_begin_workstation_identification workstation_factfile_name
229
- stations_factfile = fact_path workstation_factfile_name
230
- log.info(x) { "Workstations Facts File (Path) => #{nickname stations_factfile}" }
231
-
232
- our_user = Home.usr
233
- our_host = NetDns.instance.host_name
234
- log.info(x){ "Station Search For => #{our_user}@#{our_host}" }
235
-
236
- workstations = IniFile.load stations_factfile
237
- workstations.each_section do |station|
238
-
239
- no_user = "Workstation [#{station}] has no [username] fact."
240
- raise RuntimeError.new no_user unless workstations[station].has_key? "username"
241
-
242
- has_hostnames = workstations[station].has_key? "hostnames"
243
- no_hostnames = "[#{station}] not a workstation as no [hostnames] fact - Skip!"
244
- log.warn(x) { no_hostnames } unless has_hostnames
245
- next unless has_hostnames
246
-
247
- this_user = evaluate(workstations[station]["username"])
248
- these_hosts = evaluate(workstations[station]["hostnames"])
249
- match = this_user.eql?(our_user) && these_hosts.include?(our_host)
250
-
251
- log.info(x){ "[#{station}] with #{this_user}@#{these_hosts} - No!" } unless match
252
- next unless match
253
-
254
- log.info(x){ "[#{station}] with #{this_user}@#{these_hosts} - Matched!" }
255
- dup_msg = "Duplicate or repeat match disallowed! #{@i[:station]} and #{station}"
256
- raise RuntimeError.new dup_msg unless @i[:station].nil?
257
-
258
- @i[:station] = station
259
- @i[:workstation] = station.gsub(".", "_").to_sym
260
-
261
- end
262
-
263
- no_match_msg = "No workstation match made for [#{our_user}@#{our_host}]."
264
- raise RuntimeError.new no_match_msg if @i[:station].nil?
265
- log_end_workstation_identification workstation_factfile_name
266
- LogObject.map @i
267
-
268
- end
269
-
270
-
271
- #--
272
- #-- Knowing and setting @i[:workstation] to our workstation is key.
273
- #-- This means that the other workstations can reference files in
274
- #-- each others drives without knowing which workstation is being
275
- #-- used (see ssh.keyfile for a ghost reference example).
276
- #--
277
- #-- Now we can proceed to assimilate the entire station facts file.
278
- #--
279
- def assimilate_station_facts
280
-
281
- stations_factfile = fact_path "known-hosts.ini"
282
- assimilate_ini_file stations_factfile
283
-
284
- end
285
-
286
-
287
- # --
288
- # -- Get the path to a fact file or folder within the
289
- # -- reusable facts source tree.
290
- # --
291
- # -- The base directory is acquired by dropping down
292
- # -- three (3) directory levels from where this module
293
- # -- is and then going into reusable.facts and finally
294
- # -- appending the parameter path (file or folder).
295
- # --
296
- def fact_path fact_filename
297
- fact_basedir = File.dirname( File.dirname( File.dirname( __FILE__ ) ) )
298
- return File.join( File.join(fact_basedir,"reusable.facts"), fact_filename )
299
- end
300
-
301
-
302
- # --
303
- # -- Call instantiate() before calling populate().
304
- # --
305
- # -- This method assimilates any and all fact files
306
- # -- (recursively) found in two subdirectories
307
- # --
308
- # -- [1] - "reusable facts" and
309
- # -- [2] - the [plugin] folder
310
- # --
311
- def self.populate
312
-
313
- end
314
-
315
-
316
- # -- -------------------------------------------------------------- -- #
317
- # -- Eval and return result of parameter string if it is ruby code. -- #
318
- # -- -------------------------------------------------------------- -- #
319
- def evaluate string
320
-
321
- # -----> @todo raise a FactError here
322
-
323
- raise RuntimeError.new "Fact to Evaluate is Nil." if string.nil?
324
- return string unless string.start_with? @@eval_prefix
325
- return eval( string.gsub @@eval_prefix, "" )
326
-
327
- end
328
-
329
-
330
97
  # ----> -------------------------------------------------->
331
98
  # ----> How to Write a Custom Error
332
99
  # ----> -------------------------------------------------->
@@ -350,44 +117,6 @@ module OpenSession
350
117
  # ----> -------------------------------------------------->
351
118
 
352
119
 
353
- # -- ---------------------------------------- -- #
354
- # -- Add a fact to the main 2D fact database. -- #
355
- # -- ---------------------------------------- -- #
356
- def add_fact group_symbol, key_symbol, key_value
357
-
358
- nil_error_text = "Neither fact coordinates nor value can be nil. [group]=> #{group_symbol} [key]=> #{key_symbol} [value]=> #{key_value}"
359
- raise ArgumentError.new nil_error_text if group_symbol.nil? || key_symbol.nil? || key_value.nil?
360
-
361
- if @f.has_key? group_symbol then
362
-
363
- # --
364
- # -- This isn't the first fact within this group
365
- # -- so store the new fact key/value pair within
366
- # -- the group's namespace.
367
- # --
368
- @f[group_symbol][key_symbol] = key_value
369
-
370
- else
371
-
372
- # --
373
- # -- Create a new umbrella grouping against which
374
- # -- the new key-value pairing will be inserted.
375
- # --
376
- @f.store group_symbol, { key_symbol => key_value }
377
-
378
- end
379
-
380
- # --
381
- # -- The @s sibling hash is updated to reflect the
382
- # -- key-value pairs within the current group. This
383
- # -- allows @s to be used as shorthand within INI
384
- # -- file fact definition statements.
385
- # --
386
- @s = @f[group_symbol]
387
-
388
- end
389
-
390
-
391
120
  # -- ------------------------------------------- -- #
392
121
  # -- -- #
393
122
  # -- Template -- #
@@ -458,30 +187,39 @@ module OpenSession
458
187
 
459
188
 
460
189
 
461
- def assimilate_fact group_str, key_str, input_value
462
-
463
- grp_symbol = group_str.gsub(".", "_").to_sym
464
- key_symbol = key_str.gsub(".", "_").to_sym
190
+ # This method assimilates a two-dimensional fact bringing it into the
191
+ # fact tree fold.
192
+ #
193
+ # Once assimilated, this fact with a 2D index can be reused
194
+ # - for future fact resolution
195
+ # - by classes with access to the fact tree
196
+ # - for dynamic template resolution
197
+ #
198
+ # @param fact_group_str the first dimensional fact key
199
+ # @param fact_key_str the second dimensional fact key
200
+ # @param fact_value_str value of the fact to assimilate
201
+ def assimilate_fact fact_group_str, fact_key_str, fact_value_str
465
202
 
466
- raise ArgumentError, "Assimilating Fact [ #{group_str} ][ #{key_str} ] => Value is NIL" if input_value.nil?
203
+ grp_symbol = fact_group_str.gsub(".", "_").to_sym
204
+ key_symbol = fact_key_str.gsub(".", "_").to_sym
467
205
 
468
- fact_val = input_value.strip
206
+ raise ArgumentError, "Assimilating Fact [ #{fact_group_str} ][ #{fact_key_str} ] => Value is NIL" if fact_value_str.nil?
207
+ fact_string = fact_value_str.strip
469
208
 
470
209
  begin
471
210
 
472
- unless discard_fact?( group_str, key_str, fact_val )
473
- eval_value = evaluate(get_fact_value(fact_val))
474
- add_fact grp_symbol, get_key_symbol(key_str), eval_value
475
- end
211
+ raise ArgumentError, "Fact object in section #{fact_group_str} with key #{fact_key_str} is nil." if fact_string.nil?
212
+ eval_value = evaluate( fact_string )
213
+ add_fact grp_symbol, to_symbol(fact_key_str), eval_value
476
214
 
477
215
  rescue Exception => e
478
216
 
479
217
  log.fatal(x) { "## ##################### #################################" }
480
218
  log.fatal(x) { "## Fact Evaluation Error ---------------------------------" }
481
219
  log.fatal(x) { "## ##################### #################################" }
482
- log.fatal(x) { "## Fact Family => #{group_str}" }
483
- log.fatal(x) { "## Fact Key => #{key_str}" }
484
- log.fatal(x) { "## Fact Stmt => #{fact_val}" }
220
+ log.fatal(x) { "## Fact Family => #{fact_group_str}" }
221
+ log.fatal(x) { "## Fact Key => #{fact_key_str}" }
222
+ log.fatal(x) { "## Fact Stmt => #{fact_string}" }
485
223
  log.fatal(x) { "## Fact Error => #{e.message}" }
486
224
  log.fatal(x) { "## ##################### #################################" }
487
225
  e.backtrace.log_lines
@@ -492,9 +230,9 @@ module OpenSession
492
230
 
493
231
  unless @f.has_key? grp_symbol then
494
232
 
495
- log.debug(x){ "# -- ---------------------------------------------------------- #" }
496
- log.debug(x){ "# -- the [#{group_str}] silo facts." }
497
- log.debug(x){ "# -- ---------------------------------------------------------- #" }
233
+ log.debug(x){ "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #" }
234
+ log.debug(x){ "# @@ the [#{fact_group_str}] silo facts." }
235
+ log.debug(x){ "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #" }
498
236
 
499
237
  end
500
238
 
@@ -503,164 +241,63 @@ module OpenSession
503
241
  print_value = "****************"
504
242
  print_value = eval_value unless sensitive
505
243
 
506
- # -- -------------------------------------------------------- -- #
507
- # -- Log the human readable (fixed-width) key and value pair. -- #
508
- # -- -------------------------------------------------------- -- #
509
244
  fw_key = sprintf '%-33s', "@f[:#{grp_symbol}][:#{key_symbol}]"
510
245
  log.debug(x){ "#{fw_key} => #{print_value}" }
511
246
 
512
247
  end
513
248
 
514
249
 
515
- def discard_fact? group_str, key_str, input_value
516
-
517
- is_if = key_str.strip.end_with? "(if)"
518
- is_unless = key_str.strip.end_with?("(un)") || key_str.strip.end_with?("(unless)")
519
- return false unless is_if || is_unless
520
-
521
- two_parts = input_value.split( @@eval_prefix )
522
- no_prefix = "Conditional must be followed by eval prefix => #{two_parts}"
523
- raise RuntimeError.new no_pefix unless two_parts.length == 2
524
-
525
- conditional_part = two_parts.first.strip
526
- no_curlies_msg = "Wrap conditional in curly braces => #{conditional_part}"
527
- is_wrapped = conditional_part.start_with?("{") && conditional_part.end_with?("}")
528
- raise RuntimeError.new no_curlies_msg unless is_wrapped
529
-
530
- conditional_stmt = conditional_part[1..-2].strip
531
- log.info(x){ "Conditional Stmt => #{conditional_stmt}" }
532
- conditional_val = evaluate( @@eval_prefix + conditional_stmt )
533
- is_boolean = [true, false].include? conditional_val
534
-
535
- boolean_msg = "=> #{conditional_stmt} <= evaluated to [#{conditional_val}] not boolean."
536
- raise RuntimeError.new boolean_msg unless is_boolean
537
-
538
- return false if is_if && conditional_val
539
- return true if is_if && !conditional_val
540
-
541
- return true if is_unless && conditional_val
542
- return false if is_unless && !conditional_val
543
-
544
- raise RuntimeError.new "Unreachable if[#{is_if}] unless[#{is_unless}] => #{conditional_val}"
545
-
546
- end
547
-
548
-
549
- #--
550
- #-- Return the symbolic representation of the
551
- #-- parameter key. Periods are replaced with
552
- #-- underscores (as per the fact convention)
553
- #-- before conversion to a symbol.
554
- #--
555
- #-- Nil is not handled.
556
- #-- String is stripped beforehand just in case.
557
- #--
558
- def symbol from_string
559
250
 
251
+ # This static method converts from string to symbol.
252
+ # @param from_string the neither nil nor empty string to convert to a symbol
253
+ # @return a symbol representation of the input string
254
+ def to_symbol from_string
560
255
  return from_string.strip.gsub(".", "_").to_sym
561
-
562
256
  end
563
257
 
564
258
 
565
- #--
566
- #-- Return the (key access) symbol that represents the
567
- #-- plugin id plus a string given in the parameter.
568
- #--
569
- #-- ---------
570
- #-- Example
571
- #-- ---------
572
- #--
573
- #-- Plugin Id => ide.hub
574
- #-- Append Str => host
575
- #--
576
- #-- equals
577
- #--
578
- #-- Key String => ide.hub.host
579
- #-- Key Symbol => ide_hub_host
580
- #--
581
- #--
582
- #-- So the symbol :ide_hub_host is returned.
583
- #--
584
- def plugin_symbol append_string
585
-
586
- key_string = @i[:plugin] + "." + append_string.strip
587
- return key_string.gsub(".", "_").to_sym
588
-
589
- end
590
-
591
259
 
592
- def get_key_symbol dirty_key_string
260
+ private
593
261
 
594
- key_string = dirty_key_string.strip
595
- split_string = "(unless)"
596
- split_string = "(if)" if key_string.end_with? "(if)"
597
- split_string = "(un)" if key_string.end_with? "(un)"
598
262
 
599
- return key_string.split(split_string).first.gsub(".", "_").to_sym
600
263
 
601
- end
602
-
603
-
604
- def get_fact_value fact_value_string
605
-
606
- is_conditional = fact_value_string.start_with?("{") && fact_value_string.include?( @@eval_prefix )
607
- return fact_value_string unless is_conditional
608
-
609
- return fact_value_string.rpartition( @@eval_prefix )[1..-1].join
610
-
611
- end
264
+ def add_fact group_symbol, key_symbol, key_value
612
265
 
266
+ fact_component = "[group]=> #{group_symbol} [key]=> #{key_symbol} [value]=> #{key_value}"
267
+ nil_error_text = "Neither fact coordinates nor values can be nil. #{fact_component}"
268
+ raise ArgumentError.new nil_error_text if group_symbol.nil? || key_symbol.nil? || key_value.nil?
613
269
 
614
- def exists? fact_reference
270
+ if @f.has_key? group_symbol then
615
271
 
616
- log.info(x) { "Does Fact Exist? => #{fact_reference}" }
617
- return false if fact_reference.nil?
618
- return false if fact_reference.strip.length == 0
619
- return true if fact_reference.strip.length > 0
272
+ # -- This isn't the first fact within this group
273
+ # -- so store the new fact key/value pair within
274
+ # -- the group's namespace.
275
+ @f[group_symbol][key_symbol] = key_value
620
276
 
621
- end
277
+ else
622
278
 
279
+ # -- Create a new umbrella grouping against which
280
+ # -- the new key-value pairing will be inserted.
281
+ @f.store group_symbol, { key_symbol => key_value }
623
282
 
624
- # --
625
- # -- dot => period (full stop)
626
- # -- Deliver a "." period character
627
- # --
628
- def dot
629
- return "."
630
- end
283
+ end
631
284
 
285
+ # -- The @s sibling hash is updated to reflect the
286
+ # -- key-value pairs within the current group. This
287
+ # -- allows @s to be used as shorthand within INI
288
+ # -- file fact definition statements.
289
+ @s = @f[group_symbol]
632
290
 
633
- # --
634
- # -- colon => full colon character
635
- # -- Delivers a ":" colon character
636
- # --
637
- def colon
638
- return ":"
639
291
  end
640
292
 
641
293
 
642
- def log_begin_workstation_identification the_filename
643
-
644
- log.info(x) { "- -" }
645
- log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
646
- log.info(x) { "# -- ------------------------------------------------- -- #" }
647
- log.info(x) { "# -- [= BEGIN WORKSTATION IDENTIFICATION =] #{the_filename}" }
648
- log.info(x) { "# -- ------------------------------------------------- -- #" }
649
- log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
650
-
651
- end
652
-
294
+ def evaluate string
653
295
 
654
- def log_end_workstation_identification the_filename
296
+ # -----> @todo raise a FactError here
655
297
 
656
- log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
657
- log.info(x) { "# -- ------------------------------------------------- -- #" }
658
- log.info(x) { "# -- [= END WORKSTATION IDENTIFICATION =] #{the_filename}" }
659
- log.info(x) { "# -- ------------------------------------------------- -- #" }
660
- log.info(x) { "# @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ #" }
661
- log.info(x) { "- -" }
662
- log.info(x) { "- -" }
663
- log.info(x) { "- -" }
298
+ raise RuntimeError.new "Fact to Evaluate is Nil." if string.nil?
299
+ return string unless string.start_with? @@eval_prefix
300
+ return eval( string.gsub @@eval_prefix, "" )
664
301
 
665
302
  end
666
303