opensecret 0.0.9925 → 0.0.9949

Sign up to get free protection for your applications and to get access to all the features.
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