opensecret 0.0.9925 → 0.0.9949
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +656 -40
- data/lib/configs/README.md +58 -0
- data/lib/extension/file.rb +67 -0
- data/lib/extension/string.rb +10 -0
- data/lib/factbase/facts.opensecret.io.ini +1 -0
- data/lib/interprete.rb +334 -61
- data/lib/keytools/PRODUCE_RAND_SEQ_USING_DEV_URANDOM.txt +0 -0
- data/lib/keytools/kdf.api.rb +9 -15
- data/lib/keytools/kdf.bcrypt.rb +69 -19
- data/lib/keytools/kdf.pbkdf2.rb +112 -23
- data/lib/keytools/key.api.rb +146 -36
- data/lib/keytools/key.db.rb +94 -29
- data/lib/keytools/key.id.rb +1 -1
- data/lib/keytools/key.ident.rb +243 -0
- data/lib/keytools/key.local.rb +62 -68
- data/lib/keytools/key.pass.rb +2 -2
- data/lib/keytools/key.rb +2 -28
- data/lib/modules/{cryptology.md → README.md} +0 -0
- data/lib/session/fact.finder.rb +65 -428
- data/lib/session/time.stamp.rb +1 -28
- data/lib/usecase/cmd.rb +127 -54
- data/lib/usecase/config/README.md +57 -0
- data/lib/usecase/docker/README.md +146 -0
- data/lib/usecase/docker/docker.rb +49 -0
- data/lib/usecase/edit/README.md +43 -0
- data/lib/usecase/edit/delete.rb +46 -0
- data/lib/usecase/export.rb +40 -0
- data/lib/usecase/files/README.md +37 -0
- data/lib/usecase/files/eject.rb +56 -0
- data/lib/usecase/files/file_me.rb +78 -0
- data/lib/usecase/files/read.rb +169 -0
- data/lib/usecase/files/write.rb +89 -0
- data/lib/usecase/goto.rb +57 -0
- data/lib/usecase/id.rb +1 -1
- data/lib/usecase/import.rb +13 -30
- data/lib/usecase/init.rb +2 -17
- data/lib/usecase/jenkins/README.md +146 -0
- data/lib/usecase/jenkins/crazy_ruby_post_attempt.OLD +234 -0
- data/lib/usecase/jenkins/jenkins.rb +208 -0
- data/lib/usecase/login.rb +6 -5
- data/lib/usecase/logout.rb +1 -3
- data/lib/usecase/open.rb +11 -66
- data/lib/usecase/print.rb +40 -0
- data/lib/usecase/put.rb +34 -156
- data/lib/usecase/set.rb +2 -4
- data/lib/usecase/show.rb +138 -0
- data/lib/usecase/terraform/README.md +91 -0
- data/lib/usecase/terraform/terraform.rb +121 -0
- data/lib/usecase/token.rb +4 -80
- data/lib/usecase/update/README.md +55 -0
- data/lib/usecase/update/rename.rb +180 -0
- data/lib/usecase/use.rb +1 -3
- data/lib/usecase/verse.rb +20 -0
- data/lib/usecase/view.rb +71 -0
- data/lib/usecase/vpn/README.md +150 -0
- data/lib/usecase/vpn/vpn.ini +31 -0
- data/lib/usecase/vpn/vpn.rb +54 -0
- data/lib/version.rb +1 -1
- data/opensecret.gemspec +3 -4
- metadata +34 -35
- data/.travis.yml +0 -5
- data/CODE_OF_CONDUCT.md +0 -74
- data/LICENSE.txt +0 -21
- data/bin/ops +0 -20
- data/lib/keytools/binary.map.rb +0 -294
- data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +0 -179
- data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +0 -190
- data/lib/keytools/doc.star.schema.strategy.txt +0 -77
- data/lib/keytools/doc.using.pbkdf2.kdf.ruby +0 -95
- data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +0 -266
- data/lib/keytools/key.mach.rb +0 -248
- data/lib/keytools/keydebug.txt +0 -295
- data/lib/modules/cryptology/open.bcrypt.rb +0 -170
- data/lib/usecase/read.rb +0 -89
- data/lib/usecase/safe.rb +0 -92
data/lib/keytools/key.pass.rb
CHANGED
@@ -43,14 +43,14 @@ module OpenKey
|
|
43
43
|
assert_min_size MINIMUM_PASSWORD_SIZE
|
44
44
|
|
45
45
|
sleep(1)
|
46
|
-
puts "
|
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 "
|
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
|
data/lib/keytools/key.rb
CHANGED
@@ -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
|
320
|
-
#
|
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
|
data/lib/session/fact.finder.rb
CHANGED
@@ -1,21 +1,6 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
|
-
|
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
|
-
|
94
|
-
|
95
|
-
|
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
|
-
|
60
|
+
# This method constructs the FactFind object and tree database
|
61
|
+
# and initializers the root fact container structures.
|
62
|
+
def initialize
|
136
63
|
|
137
|
-
|
138
|
-
|
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
|
-
|
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
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
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
|
-
|
203
|
+
grp_symbol = fact_group_str.gsub(".", "_").to_sym
|
204
|
+
key_symbol = fact_key_str.gsub(".", "_").to_sym
|
467
205
|
|
468
|
-
|
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
|
-
|
473
|
-
|
474
|
-
|
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 => #{
|
483
|
-
log.fatal(x) { "## Fact Key => #{
|
484
|
-
log.fatal(x) { "## Fact Stmt => #{
|
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){ "#
|
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
|
-
|
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
|
-
|
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
|
-
|
270
|
+
if @f.has_key? group_symbol then
|
615
271
|
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
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
|
-
|
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
|
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
|
-
|
296
|
+
# -----> @todo raise a FactError here
|
655
297
|
|
656
|
-
|
657
|
-
|
658
|
-
|
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
|
|