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