opensecret 0.0.2 → 0.0.4

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -0
  3. data/README.md +2 -2
  4. data/bin/opensecret +3 -6
  5. data/lib/opensecret-domain.ini +23 -0
  6. data/lib/opensecret.rb +30 -2
  7. data/lib/opensecret/additions/array.rb +117 -0
  8. data/lib/opensecret/additions/dir.rb +35 -0
  9. data/lib/opensecret/additions/string.rb +312 -0
  10. data/lib/opensecret/commons/eco.cmdline.rb +446 -0
  11. data/lib/opensecret/commons/eco.faculty.rb +364 -0
  12. data/lib/opensecret/commons/eco.system.rb +437 -0
  13. data/lib/opensecret/commons/eco.systems.rb +98 -0
  14. data/lib/opensecret/{safe.rb → delegate.rb} +4 -2
  15. data/lib/opensecret/eco.do.rb +46 -0
  16. data/lib/opensecret/executors/crypt.keys/crypt.keys.ini +79 -0
  17. data/lib/opensecret/executors/crypt.keys/crypt.keys.rb +68 -0
  18. data/lib/opensecret/executors/decrypt/decrypt.ini +64 -0
  19. data/lib/opensecret/executors/decrypt/decrypt.rb +49 -0
  20. data/lib/opensecret/executors/encrypt/encrypt.ini +55 -0
  21. data/lib/opensecret/executors/encrypt/encrypt.rb +82 -0
  22. data/lib/opensecret/factbase/hub-runtime.ini +123 -0
  23. data/lib/opensecret/factbase/known-hosts.ini +75 -0
  24. data/lib/opensecret/factbase/published.facts/blobbolicious-facts.ini +553 -0
  25. data/lib/opensecret/factbase/published.facts/credential-facts.ini +40 -0
  26. data/lib/opensecret/factbase/published.facts/infrastructure-facts.ini +63 -0
  27. data/lib/opensecret/factbase/readme.md +24 -0
  28. data/lib/opensecret/factbase/retired.facts/maven.database.ide.facts.ini +127 -0
  29. data/lib/opensecret/factbase/retired.facts/s3-upload-block-facts.ini +17 -0
  30. data/lib/opensecret/plugins.io/cipher/crypto.rb +174 -0
  31. data/lib/opensecret/plugins.io/error/eco.exceptions.rb +24 -0
  32. data/lib/opensecret/plugins.io/facts/fact.chars.rb +66 -0
  33. data/lib/opensecret/plugins.io/facts/fact.factor.rb +156 -0
  34. data/lib/opensecret/plugins.io/facts/fact.locator.rb +105 -0
  35. data/lib/opensecret/plugins.io/facts/fact.reader.rb +137 -0
  36. data/lib/opensecret/plugins.io/facts/fact.tree.rb +661 -0
  37. data/lib/opensecret/plugins.io/file/file.rb +483 -0
  38. data/lib/opensecret/plugins.io/git/git.flow.rb +388 -0
  39. data/lib/opensecret/plugins.io/logs/log.object.rb +89 -0
  40. data/lib/opensecret/plugins.io/logs/logging.rb +203 -0
  41. data/lib/opensecret/plugins.io/time/time.stamp.rb +425 -0
  42. data/lib/opensecret/version.rb +2 -2
  43. data/opensecret.gemspec +8 -13
  44. metadata +68 -18
@@ -0,0 +1,446 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # -- --------------------------------------------------------------------------------- -- #
4
+ # -- The [Command Interpreter] -- #
5
+ # -- --------------------------------------------------------------------------------- -- #
6
+ # -- -- #
7
+ # -- From the command line we receive the below asset groups. -- #
8
+ # -- -- #
9
+ # -- [1] - major use case commands like "create", "register", "destroy" -- #
10
+ # -- [2] - specifiers telling us "create what", "destroy which ones" -- #
11
+ # -- [3] - boolean flags that dictate which way the hammer should fall -- #
12
+ # -- [4] - option / arg config pairs (options can be long or short) -- #
13
+ # -- -- #
14
+ # -- Some flags and options are mandatory - others are optional. Argument types -- #
15
+ # -- are usually => [ booleans, strings, lists, sets or numbers ]. -- #
16
+ # -- -- #
17
+ # -- --------------------------------------------------------------------------------- -- #
18
+ # -- Art or Science -- #
19
+ # -- --------------------------------------------------------------------------------- -- #
20
+ # -- -- #
21
+ # -- Parsing the command line and returning concise error messages is much more -- #
22
+ # -- [ART] than it is [SCIENCE]. This is because the permutations and combinations -- #
23
+ # -- are mind bogglingly vast. Hence this code is strictly ["best efforts"]. -- #
24
+ # -- -- #
25
+ # -- That said, the invoked commands should be belt and braces in processing the -- #
26
+ # -- arguments and switches provided on the command line. -- #
27
+ # -- -- #
28
+ # -- This command interpreter in no way absolves the evoked software from the legwork -- #
29
+ # -- of security, validation and semantic assessments. -- #
30
+ # -- -- #
31
+ # -- --------------------------------------------------------------------------------- -- #
32
+ class CmdLine
33
+ include Singleton
34
+
35
+ attr_reader :create
36
+ attr_reader :task
37
+ attr_reader :do_read_db_names
38
+ attr_reader :do_register_user
39
+ attr_reader :do_destroy_app
40
+
41
+ attr_reader :key_values
42
+ attr_reader :args_cache
43
+ attr_reader :args_after
44
+
45
+
46
+ def initialize
47
+
48
+ # -- ----------------------------------------------------------- --- #
49
+ # -- If no commands to interpret - assume the caller needs help. --- #
50
+ # -- ----------------------------------------------------------- --- #
51
+ ARGV.push "--help" if ARGV.length == 0
52
+
53
+ @key_values = {}
54
+ @args_cache = [].replace ARGV
55
+
56
+ # --- ------------------------------------------------------------- --- #
57
+ # --- [--help] is a peripheral command with no [do] [what] pattern. --- #
58
+ # --- ------------------------------------------------------------- --- #
59
+ print_help_screen if ARGV.include? "--help"
60
+ print_help_screen if ARGV.include? "-h"
61
+
62
+ # --- -------------------------------------------------- --- #
63
+ # --- Each line below pertains to a [do] [what] command. --- #
64
+ # --- -------------------------------------------------- --- #
65
+ read_eco_create_args if command_matches? "create", "what", "w"
66
+ read_read_db_names_args if command_matches? "read", "s3", "s"
67
+ read_aws_register_args if command_matches? "register", "aws-user", "a"
68
+ read_destroy_app_args if command_matches? "destroy", "app", "a"
69
+ read_task_args if command_matches? "task", "what", "w"
70
+
71
+ # --- --------------------------------------------------------- --- #
72
+ # --- Notify caller if [do] [what] portion could not be mapped. --- #
73
+ # --- --------------------------------------------------------- --- #
74
+ handle_cmd_match_fail if @options_parser == nil
75
+
76
+ begin
77
+
78
+ @options_parser.parse!
79
+ @args_after = ARGV
80
+
81
+ missing_args = @mandatory_options.select{ |param| @key_values[param].nil? }
82
+ unless missing_args.empty?
83
+ raise OptionParser::MissingArgument.new(missing_args.join(', '))
84
+ end
85
+
86
+ rescue OptionParser::InvalidOption => exception
87
+
88
+ log.warn(ere) { "#--- ---------------------------------------------- --- #" }
89
+ log.warn(ere) { "#--- eco did not recognize a command option. --- #" }
90
+ log.warn(ere) { "#--- ---------------------------------------------- --- #" }
91
+ log.warn(ere) { "#--- #{exception}" }
92
+ log.warn(ere) { "#--- #{exception.inspect}" }
93
+
94
+ #### Fix this if too spurious
95
+ #### Fix this if too spurious
96
+ #### Fix this if too spurious
97
+ #### Fix this if too spurious
98
+ ################ puts exception.backtrace if @@VERBOSE_MODE
99
+
100
+ log.warn(ere) { "#{exception.backtrace}" } ##### may be add if ARGV.include? "--debug"
101
+ log.warn(ere) { @options_parser.help }
102
+ log.warn(ere) { "#--- ---------------------------------------------- --- #" }
103
+
104
+ # @@
105
+ # @@ No need to exit from this - this script does not need
106
+ # @@ to be hard-coded with every command line option.
107
+ # @@ (We need only know the [Mandatory] ones which is
108
+ # @@ handled by the below rescue block.
109
+ # @@
110
+
111
+ ################## DELETE ME ASAP
112
+ ############## exit
113
+ ################## DELETE ME ASAP
114
+
115
+
116
+ rescue OptionParser::MissingArgument => missing_arg
117
+
118
+ log.fatal(ere) { $!.to_s }
119
+ log.fatal(ere) { @options_parser }
120
+ exit
121
+
122
+ end
123
+
124
+ end
125
+
126
+
127
+ # --
128
+ # -- Returns true if the option text was included on the command line.
129
+ # --
130
+ # -- This method does not look within a list of values. Only call this
131
+ # -- method if the text is a free form switch WITHOUT an equal sign.
132
+ # --
133
+ def self.has? a_string
134
+ return CmdLine.instance.args_cache.include? a_string
135
+ end
136
+
137
+
138
+ # --
139
+ # -- Return true if symbol (switch) was included on the command line.
140
+ # --
141
+ # -- WARNING - Do not use externally as the line is cleared.
142
+ # -- - Call has? like =] if CmdLine.has? --debug
143
+ # --
144
+ def self.include? a_symbol
145
+ return CmdLine.instance.key_values.include? a_symbol
146
+ end
147
+
148
+
149
+ # -- ---------------------------------------------------------------------------- -- #
150
+ # -- Does the command line contain a specific command and a flag in either of its -- #
151
+ # -- forms - long and short. If yes then this method will return true. -- #
152
+ # -- ---------------------------------------------------------------------------- -- #
153
+ def command_matches? cmd_str, flag_long, flag_short
154
+
155
+ return ( ARGV.include?( cmd_str ) && ARGV.include?("--#{flag_long}") ) ||
156
+ ( ARGV.include?( cmd_str ) && ARGV.include?("-#{flag_short}") )
157
+
158
+ end
159
+
160
+
161
+ # -- ---------------------------------------------------------------------------- -- #
162
+ # -- forms - long and short. If yes then this method will return true. -- #
163
+ # -- ---------------------------------------------------------------------------- -- #
164
+ def handle_cmd_match_fail
165
+
166
+ log.fatal(ere) { " # - ------------------------------------------------------------ - #" }
167
+ log.fatal(ere) { " # - eco command ==> could not match == [do] [what] [how] [where] - #" }
168
+ log.fatal(ere) { " # - ------------------------------------------------------------ - #" }
169
+ log.fatal(ere) { " eco [do] [what]" }
170
+ log.fatal(ere) { " Could not match the [do what] branch of the command tree." }
171
+ log.fatal(ere) { " [do] is CRUD based eg [create, register, read, update, destroy]." }
172
+ log.fatal(ere) { " The [what] part tells the command interpreter what you want to do." }
173
+ log.fatal(ere) { " eco optional arguments == [how] [where] [to]" }
174
+ log.fatal(ere) { " [how] - do it how eg | --clean | --dry-run |" }
175
+ log.fatal(ere) { " [where] - (on what) eg | --cloud | --local |" }
176
+ log.fatal(ere) { " [to] - do it to eg | --eco-system | --service |" }
177
+
178
+ exit
179
+
180
+ end
181
+
182
+
183
+ ## --- --------------------------------------------------------- --- ##
184
+ ## --- How to use Declarative and Dynamic Command Interpretation --- ##
185
+ ## --- --------------------------------------------------------- --- ##
186
+ ## ---
187
+ ## --- Once SREs are familiar with this command interpreter class
188
+ ## --- the next refactor step is to generate the whole thing dynamically.
189
+ ## --- I will probably write a ruby gem to do exactly this.
190
+ ## ---
191
+ ## --- The essence is to create a JSON or YAML configuration file that
192
+ ## --- holds the command line interpretation variables. This is used to
193
+ ## --- dynamically generate the optparse blocks.
194
+ ## ---
195
+ ## --- --------------------------------------------------------- --- ##
196
+ ## --- How to use Dynamically Generate the Help Screen --- ##
197
+ ## --- --------------------------------------------------------- --- ##
198
+ ## ---
199
+ ## --- To generate the help screen you can loop round calling each
200
+ ## --- parser block (without any actual cmd line arguments)!
201
+ ## ---
202
+ ## --- Then you loop doing a to_string puts opt_parser for each
203
+ ## --- parser and all the options will be ejected automatically!
204
+ ## ---
205
+ ## --- You are done when all read methods vanish (ruby magic)!
206
+ ## ---
207
+ ## --- --------------------------------------------------------- --- ##
208
+
209
+
210
+ ## --- ---------------------- --- ##
211
+ ## --- Create the application --- ##
212
+ ## --- ---------------------- --- ##
213
+ def read_eco_create_args
214
+
215
+ ## ---------------------------------------------------------- #
216
+ @create = true
217
+ @mandatory_options = [:service_descriptors]
218
+ ## ---------------------------------------------------------- #
219
+ @options_parser = OptionParser.new do | the_options |
220
+
221
+ the_options.banner = " eco create --what => create which eco systems\n\n"
222
+
223
+ ## the_options.on( "-f", "--versions-file FILE_PATH", "Service versions file in JSON (mandatory)") do | versions_file |
224
+
225
+ ## @key_values[:versions_file] = versions_file
226
+
227
+ ## end
228
+
229
+ the_options.on( "-w", "--what mongo,email,...", Array, "Comma separated service descriptors (mandatory)") do | service_descriptors_list |
230
+
231
+ @key_values[:service_descriptors] = service_descriptors_list
232
+
233
+ end
234
+
235
+ end
236
+
237
+ end
238
+
239
+
240
+ ## --- -------------------- --- ##
241
+ ## --- Register an AWS User --- ##
242
+ ## --- -------------------- --- ##
243
+ def read_aws_register_args
244
+
245
+ ## ---------------------------------------------------------- #
246
+ @do_register_user = true
247
+ @mandatory_options = [:aws_user, :aws_user_id, :aws_password]
248
+ ## ---------------------------------------------------------- #
249
+ @options_parser = OptionParser.new do | the_options |
250
+
251
+ the_options.banner = " eco register --aws-user => options to register [aws credentials]\n\n"
252
+
253
+ the_options.on( "-a", "--aws-user", "Registering AWS Credentials") do
254
+
255
+ @key_values[:aws_user] = true
256
+
257
+ end
258
+
259
+ the_options.on( "-u", "--aws-user-id AWS_USER_ID", "Your AWS User ID Key (mandatory)") do | aws_user_id |
260
+
261
+ @key_values[:aws_user_id] = aws_user_id
262
+
263
+ end
264
+
265
+ the_options.on( "-p", "--aws-password AWS_PASSWORD", "Your AWS User Password (mandatory)") do | aws_password |
266
+
267
+ @key_values[:aws_password] = aws_password
268
+
269
+ end
270
+
271
+ end
272
+
273
+ end
274
+
275
+
276
+ # --
277
+ # -- Task does something (encrypts or decrypts) some text.
278
+ # --
279
+ # -- main command => encrypt
280
+ # -- mandatory arg => --text=abc123 or -t
281
+ # --
282
+ # --
283
+ def read_task_args
284
+
285
+ ## ------------------------------------------------------------------ #
286
+ @task = true
287
+ @mandatory_options = [:service_descriptors]
288
+ ## ------------------------------------------------------------------ #
289
+ @options_parser = OptionParser.new do | the_options |
290
+
291
+ the_options.banner = " eco encrypt --text => options to encrypt [some text]\n\n"
292
+
293
+
294
+ the_options.on( "-w", "--what mongo,email,...", Array, "Comma separated descriptors (mandatory)") do | service_descriptors_list |
295
+
296
+ @key_values[:service_descriptors] = service_descriptors_list
297
+
298
+ end
299
+
300
+
301
+ the_options.on( "-n", "--name NAME", "The name (reference) of the encryptee.") do | name |
302
+
303
+ @key_values[:name] = name
304
+
305
+ end
306
+
307
+ the_options.on( "-f", "--file FILE", "The name of the file whose text is to be decrypted") do | file |
308
+
309
+ @key_values[:file] = file
310
+
311
+ end
312
+
313
+ end
314
+
315
+ end
316
+
317
+
318
+ ## --- -------------------------- --- ##
319
+ ## --- Read the DB Name Arguments --- ##
320
+ ## --- -------------------------- --- ##
321
+ def read_read_db_names_args
322
+
323
+ ## ---------------------------------------------------------- #
324
+ @do_read_db_names = true
325
+ @mandatory_options = [:read_db_names]
326
+ ## ---------------------------------------------------------- #
327
+ @options_parser = OptionParser.new do | the_options |
328
+
329
+ the_options.banner = " eco read --s3 => reading names of customer databases in S3\n\n"
330
+
331
+ the_options.on( "-s", "--s3", "Available Customer DBs in S3") do
332
+
333
+ @key_values[:read_db_names] = true
334
+
335
+ end
336
+
337
+ end
338
+
339
+ end
340
+
341
+
342
+ ## --- -------------------------------------------------------- --- ##
343
+ ## --- Destroy and reclaim resources from created applications. --- ##
344
+ ## --- -------------------------------------------------------- --- ##
345
+ def read_destroy_app_args
346
+
347
+ ## ---------------------------------------------------------- #
348
+ @do_destroy_app = true
349
+ @mandatory_options = [:destroy_app, :key]
350
+ ## ---------------------------------------------------------- #
351
+ @options_parser = OptionParser.new do | the_options |
352
+
353
+ the_options.banner = " eco destroy --app => destroying an eco system\n\n"
354
+
355
+ the_options.on( "-a", "--app", "Destroy enterprise application") do
356
+
357
+ @key_values[:destroy_app] = true
358
+
359
+ end
360
+
361
+ the_options.on( "-k", "--key APP_KEY", "Key (ref) of app to delete (mandatory)") do | key_value |
362
+
363
+ @key_values[:key] = key_value
364
+
365
+ end
366
+
367
+ end
368
+
369
+ end
370
+
371
+
372
+ ## --- --------------------------------------------------------- --- ##
373
+ ## --- How to use Declarative and Dynamic Command Interpretation --- ##
374
+ ## --- --------------------------------------------------------- --- ##
375
+ ## ---
376
+ ## --- Once SREs are familiar with this command interpreter class
377
+ ## --- the next refactor step is to generate the whole thing dynamically.
378
+ ## --- I will probably write a ruby gem to do exactly this.
379
+ ## ---
380
+ ## --- The essence is to create a JSON or YAML configuration file that
381
+ ## --- holds the command line interpretation variables. This is used to
382
+ ## --- dynamically generate the optparse blocks.
383
+ ## ---
384
+ ## --- --------------------------------------------------------- --- ##
385
+ ## --- How to use Dynamically Generate the Help Screen --- ##
386
+ ## --- --------------------------------------------------------- --- ##
387
+ ## ---
388
+ ## --- To generate the help screen you can loop round calling each
389
+ ## --- parser block (without any actual cmd line arguments)!
390
+ ## ---
391
+ ## --- Then you loop doing a to_string puts opt_parser for each
392
+ ## --- parser and all the options will be ejected automatically!
393
+ ## ---
394
+ ## --- --------------------------------------------------------- --- ##
395
+
396
+ def print_help_screen
397
+
398
+ read_eco_create_args
399
+ args_documented = @options_parser.to_s
400
+ read_aws_register_args
401
+ args_documented = "#{args_documented}\n\n#{@options_parser.to_s}"
402
+ read_read_db_names_args
403
+ args_documented = "#{args_documented}\n\n#{@options_parser.to_s}"
404
+ read_destroy_app_args
405
+ args_documented = "#{args_documented}\n\n#{@options_parser.to_s}"
406
+
407
+ if false then
408
+ log.warn(ere) { " # --- --------------------------------------------------------------------- --- #" }
409
+ log.warn(ere) { " # --- create executable => => [only for DevOps and SRE personnel] --- #" }
410
+ log.warn(ere) { " # --- --------------------------------------------------------------------- --- #" }
411
+
412
+ log.warn(ere) { " ruby eco-invoke.rb [do] [what]" }
413
+ log.warn(ere) { " ruby eco-invoke.rb [create] [--exe]" }
414
+ log.warn(ere) { " ruby eco-invoke.rb create --exe" }
415
+ end
416
+
417
+ log.warn(ere) { " # --- --------------------------------------------------------------------- --- #" }
418
+ log.warn(ere) { " # --- eco peripheral commands --- #" }
419
+ log.warn(ere) { " # --- --------------------------------------------------------------------- --- #" }
420
+ log.warn(ere) { " eco --help" }
421
+ log.warn(ere) { " eco -h" }
422
+ log.warn(ere) { " # --- --------------------------------------------------------------------- --- #" }
423
+ log.warn(ere) { " # --- eco arguments documentation --- #" }
424
+ log.warn(ere) { " # --- --------------------------------------------------------------------- --- #" }
425
+ log.warn(ere) { args_documented }
426
+
427
+ exit
428
+
429
+ end
430
+
431
+
432
+ # -- -------------------------------------------------------- #
433
+ # -- [Cold Call Pattern] -- #
434
+ # -- If class has no [internal] dependencies it can -- #
435
+ # -- initialize itself ignoring any require order. -- #
436
+ # -- -- #
437
+ # -- [Advantage of Cold Call Pattern] -- #
438
+ # -- The class [dependency] is not [hardcoded] into -- #
439
+ # -- any other class. Others benefit from initialize -- #
440
+ # -- activities without a create / handshake call. -- #
441
+ # -- -- #
442
+ # -- -------------------------------------------------------- #
443
+ CmdLine.instance
444
+
445
+
446
+ end
@@ -0,0 +1,364 @@
1
+ #!/usr/bin/ruby
2
+
3
+ # --
4
+ # -- eco-system [provisioning] begins in earnest here. By making
5
+ # -- a [super] call (at the beginning, middle or end) - eco-systems
6
+ # -- can extend the functionality provided here.
7
+ # --
8
+ # -- To prevent this code running, child classes must provide their
9
+ # -- own provision along an (optional) alternative implementation.
10
+ # --
11
+ class EcoFaculty
12
+
13
+ attr_reader :eco_id_str
14
+
15
+ #--
16
+ #-- Get the folder path to the eco-system [plugin]
17
+ #-- source directory.
18
+ #--
19
+ #-- Also see the plugin runtime directory which is
20
+ #-- the runtime folder created by the method named
21
+ #-- => EcoFaculty.instantiate_runtime
22
+ #--
23
+ #-- -------------
24
+ #-- Dependency
25
+ #-- -------------
26
+ #--
27
+ #-- The method :core_provisioning in the plugin must
28
+ #-- exist and must have been "Required".
29
+ #--
30
+ def plugin_src_dir
31
+
32
+ return File.dirname self.method(:core_provisioning).source_location.first
33
+
34
+ end
35
+
36
+
37
+ # --
38
+ # -- Facts are the business of this eco-system behaviour class.
39
+ # -- This provision method will collect the eco-system plugin id
40
+ # -- and from that assimilate all known fact files.
41
+ # --
42
+ def provision
43
+
44
+ @eco_id_str = SnapFlat.do self.class.name
45
+ @eco_id_sym = @eco_id_str.gsub(".", "_").to_sym
46
+ @plugin_path = plugin_src_dir
47
+
48
+ FactTree.instance.instantiate @eco_id_str, @plugin_path
49
+ FactTree.instance.assimilate_instance_facts
50
+
51
+ instantiate_runtime FactTree.instance.f
52
+
53
+ FactTree.instance.identify_my_workstation
54
+ FactTree.instance.assimilate_station_facts
55
+ FactTree.instance.assimilate_plugin_facts
56
+ FactTree.instance.assimilate_general_facts
57
+
58
+ @c = FactTree.instance.f
59
+ @i = FactTree.instance.i
60
+ @p = FactTree.instance.f[@eco_id_sym]
61
+
62
+ # --
63
+ # -- assimilate and configure aws cloud credentials
64
+ # -- if the plugin fact [aws.creds.dir] exists.
65
+ # --
66
+ configure_aws_credentials if @c[:aws][:creds_exist?]
67
+
68
+ end
69
+
70
+
71
+ # --
72
+ # -- Assimilate and configure aws cloud credentials.
73
+ # -- Call this method only when it is certain that the
74
+ # -- hub fact [aws.creds.dir] exists.
75
+ # --
76
+ # -- By convention this method expects the decrypted
77
+ # -- AWS user credential INI file to be inside the above
78
+ # -- dir with name <<plugin.id>>.aws.credentials.ini
79
+ # --
80
+ def configure_aws_credentials
81
+
82
+ # --
83
+ # -- Before the rubber can hit the road - we must
84
+ # -- first read in the secret credentials. To avoid
85
+ # -- logging the secrets we read it up into its own
86
+ # -- isolated mini fact database.
87
+ # --
88
+ # -- The aws creds database lives just long enough
89
+ # -- to programmatical configure the AWS IAM user.
90
+ # --
91
+ FactTree.instance.assimilate_ini_file @c[:aws][:creds_path]
92
+ aws_creds = FactTree.instance.f
93
+ log.info(ere) { "AWS Region Key => #{aws_creds[@eco_id_sym][:aws_region_key]}" }
94
+
95
+ # --
96
+ # -- Now the rubber can hit the road and we configure
97
+ # -- the AWS Ruby SDK with the IAM credentials that
98
+ # -- have been recovered.
99
+ # --
100
+ Aws.use_bundled_cert!
101
+ Aws.config.update({
102
+ :access_key_id => aws_creds[@eco_id_sym][:aws_access_key],
103
+ :secret_access_key => aws_creds[@eco_id_sym][:aws_secret_key],
104
+ :region => aws_creds[@eco_id_sym][:aws_region_key]
105
+ })
106
+
107
+ # --
108
+ # -- Temporarily add the AWS credentials to the environment
109
+ # -- variables so that infrastructure provisioning tools like
110
+ # -- Terraform can access the cloud cedentials.
111
+ # --
112
+ EnvVar.new.write_env_var "AWS_ACCESS_KEY_ID", aws_creds[@eco_id_sym][:aws_access_key]
113
+ EnvVar.new.write_env_var "AWS_SECRET_ACCESS_KEY", aws_creds[@eco_id_sym][:aws_secret_key]
114
+ EnvVar.new.write_env_var "AWS_DEFAULT_REGION", aws_creds[@eco_id_sym][:aws_region_key]
115
+
116
+ end
117
+
118
+
119
+ # --
120
+ # -- This key (instantiation) behaviour
121
+ # --
122
+ # -- 1 - [CREATES] the runtime plugin folder [then]
123
+ # -- 2 - [COPIES] into it files from the plugin source folder [and]
124
+ # -- 3 - [NOTIFY] (point) log utility to new (plugin dir) logfile
125
+ # --
126
+ # -- Before continuing the fact assimilation process we now
127
+ # -- know enough to instantiate the plugin runtime folder and
128
+ # -- start logging to a file within it.
129
+ # --
130
+ def instantiate_runtime core_db
131
+
132
+ Throw.if_exists core_db[:runtime][:dir]
133
+
134
+ # --
135
+ # -- Create the new runtime directory then
136
+ # -- Copy asset templates into it.
137
+ # -- Note that these templates contain unresolved fact directives.
138
+ # --
139
+ FileUtils.mkdir_p core_db[:runtime][:dir] unless File.exists? core_db[:runtime][:dir]
140
+ FileUtils.copy_entry @plugin_path, core_db[:runtime][:dir]
141
+ FactTree.instance.add_dir_to_identity core_db[:runtime][:dir]
142
+
143
+ # --
144
+ # -- Evaluate the absolute [logfile path] within
145
+ # -- the eco system instance runtime directory.
146
+ # --
147
+ # -- Then tell the logging.rb MIXIN that the new logfile
148
+ # -- at (logfile_path) is ready to be used.
149
+ # -- This MIXIN affects all classes that have log write statements
150
+ # --
151
+ logfile_path = File.join core_db[:runtime][:dir], "#{core_db[:runtime][:dirname]}.log"
152
+ log.info(ere) { "[LAST] - The last logging statement going to STDOUT but NOT logfile." }
153
+ set_logfile_path logfile_path
154
+ log.info(ere) { "[FIRST] - The first log going to [both] STDOUT and a logfile." }
155
+ log.info(ere) { "logfile => #{logfile_path}" }
156
+ log.info(ere) { "Log Level is now set @ => #{log.level.to_s}" }
157
+
158
+ end
159
+
160
+
161
+ # --
162
+ # -- Write the entirery of command line options into
163
+ # -- the fact database as an array.
164
+ # --
165
+ # -- Group Symbol => :cmd_line
166
+ # -- Key Symbol => :options
167
+ # -- Value Type => (Array of Strings)
168
+ # --
169
+ #### def read_cmdline_facts
170
+
171
+ #### puts
172
+ #### puts "# -- ------------------ -------------------------- --- "
173
+ #### puts "# -- Command Line Facts -------------------------- --- "
174
+ #### puts "# -- ------------------ -------------------------- --- "
175
+ #### pp CmdLine.instance.args_cache
176
+ #### puts "# -- ------------------ -------------------------- --- "
177
+ #### puts
178
+
179
+ #### @fact_db.add_fact :cmd_line, :options, CmdLine.instance.args_cache
180
+
181
+ #### end
182
+
183
+
184
+ # --
185
+ # -- Scan every file in the eco plugin directory in search of
186
+ # -- fact placeholder keys contained in the fact database.
187
+ # --
188
+ # -- Once found, replace them with the corresponding value.
189
+ # --
190
+ # -- -----------
191
+ # -- Warning
192
+ # -- -----------
193
+ # -- This behaviour is [NOT RECURSIVE].
194
+ # -- Only files in the folder are examined.
195
+ # -- Folders in the folder are ignored.
196
+ # --
197
+ def replace_placeholders
198
+
199
+ Files.find_replace Refactor.flatten(@c), @c[:runtime][:dir]
200
+
201
+ end
202
+
203
+
204
+ ## --- ---------------------------------------------- --- #
205
+ ## --- Return the factthat is --- #
206
+ ## --- [1] under the current eco plugin banner --- #
207
+ ## --- [2] has the key symbol in the parameter --- #
208
+ ## --- ---------------------------------------------- --- #
209
+ def get_eco_fact key_symbol
210
+ error_msg = "fact 4 group => #{@eco_id_sym} + key => #{key_symbol} not in db."
211
+ raise ArgumentError.new "\n\n#{error_msg}\n\n" unless eco_fact_exists? key_symbol
212
+ return @c[@eco_id_sym][key_symbol]
213
+ end
214
+
215
+
216
+ ## --- ---------------------------------------------- --- #
217
+ ## --- Return the fact that is --- #
218
+ ## --- [1] under the current eco plugin banner --- #
219
+ ## --- [2] has the key symbol in the parameter --- #
220
+ ## --- ---------------------------------------------- --- #
221
+ def e_fact key_symbol
222
+ error_msg = "fact 4 group => #{@eco_id_sym} + key => #{key_symbol} not in db."
223
+ raise ArgumentError.new "\n\n#{error_msg}\n\n" unless eco_fact_exists? key_symbol
224
+ return @c[@eco_id_sym][key_symbol]
225
+ end
226
+
227
+
228
+ ## --- ---------------------------------------------- --- #
229
+ ## --- Return the fact that is --- #
230
+ ## --- [1] under the current eco plugin banner --- #
231
+ ## --- [2] has the key symbol in the parameter --- #
232
+ ## --- ---------------------------------------------- --- #
233
+ def plugin_fact key_symbol
234
+ error_msg = "fact 4 group => #{@eco_id_sym} + key => #{key_symbol} not in db."
235
+ raise ArgumentError.new "\n\n#{error_msg}\n\n" unless eco_fact_exists? key_symbol
236
+ return @c[@eco_id_sym][key_symbol]
237
+ end
238
+
239
+
240
+ # --
241
+ # -- Return [true] if a fact exists that is
242
+ # --
243
+ # -- [1] under the banner of the current plugin id
244
+ # -- [2] with a key symbol matching the parameter
245
+ # -- [3] is neither empty nor solely whitespace
246
+ # --
247
+ def plugin_fact_exists? key_symbol
248
+ return db_fact_exists? @eco_id_sym, key_symbol
249
+ end
250
+
251
+
252
+ ## --- ------------------------------------------------------ --- #
253
+ ## --- Return [true] if a fact exists that is --- #
254
+ ## --- [1] under the banner of the current plugin id --- #
255
+ ## --- [2] with a key symbol matching the parameter --- #
256
+ ## --- [3] is neither empty nor solely whitespace --- #
257
+ ## --- ------------------------------------------------------ --- #
258
+ def eco_fact_exists? key_symbol
259
+ return db_fact_exists? @eco_id_sym, key_symbol
260
+ end
261
+
262
+
263
+ ## --- ---------------------------------------------------------- --- #
264
+ ## --- Return [true] if a fact exists that --- #
265
+ ## --- [1] DOES NOT ASSUME FACT IS A STRING
266
+ ## --- [1] carries the primary symbol key in 1st parameter --- #
267
+ ## --- [2] carries the secondary symbol key in 2nd parameter --- #
268
+ ## --- [3] is neither empty nor solely whitespace --- #
269
+ ## --- ---------------------------------------------------------- --- #
270
+ def db_fact_exists? group_symbol, key_symbol
271
+ return false unless @c.has_key? group_symbol
272
+ fact_value = @c[group_symbol][key_symbol]
273
+ return !fact_value.nil?
274
+ end
275
+
276
+
277
+ ## --- [1] ASSUMES THAT FACT IS A STRING --- #
278
+ def string_fact_exists? group_symbol, key_symbol
279
+ return false unless @c.has_key? group_symbol
280
+ fact_value = @c[group_symbol][key_symbol]
281
+ return false if fact_value.nil?
282
+ return fact_value.strip.length > 0
283
+ end
284
+
285
+
286
+ # --
287
+ # -- If eco plugins wish to update only [SOME] of the properties
288
+ # -- within [application.properties] then they should set
289
+ # --
290
+ # -- fact key => @c[@c[:plugin][:id]][:props_src_path]
291
+ # -- fact val => "/path/to/application.properties
292
+ # --
293
+ # -- The property file will be assimilated and the key / value
294
+ # -- pairs will be attached under the :app_properties grouping
295
+ # -- symbol. One o more facts can be updated (overwritten) and
296
+ # -- later written back (see write_app_properties)
297
+ # --
298
+ def read_properties
299
+
300
+ return unless eco_fact_exists? :props_src_path
301
+ @fact_db.assimilate_property_file e_fact(:props_src_path), :app_properties
302
+
303
+ end
304
+
305
+
306
+ # --
307
+ # -- If eco plugins wish the properties in the database under
308
+ # -- :app_properties to be written to create (or overwrite)
309
+ # -- the app properties they should create
310
+ # --
311
+ # -- fact key => @c[@c[:plugin][:id]][:props_dst_dirs]
312
+ # -- fact val => "/path/to/application.properties
313
+ # --
314
+ # -- ----------------
315
+ # -- Warning (Array)
316
+ # -- ----------------
317
+ # -- The [:props_dst_dirs] fact is an [ARRAY].
318
+ # -- The same property key/value pairs will be serialized into
319
+ # -- each file url stated in the array. The [:props_dst_dirs]
320
+ # -- is (in contrast) a simple single filename.
321
+ # --
322
+ # -- -----------------------------
323
+ # -- (Optional) - Src Properties
324
+ # -- -----------------------------
325
+ # -- Plugins do not need to set the :app_props_src_path key.
326
+ # -- If they only set the (dst) key, any properties set in the
327
+ # -- fact database will still be written out.
328
+ # --
329
+ def write_properties
330
+
331
+ return unless eco_fact_exists? :props_dst_dirs
332
+ property_files = e_fact :props_dst_dirs
333
+
334
+ property_files.each do | property_dir |
335
+
336
+ Dir.mkdir property_dir unless File.exists? property_dir
337
+ Files.write_properties(
338
+ @c[:app_properties],
339
+ property_dir,
340
+ e_fact(:props_dst_name)
341
+ )
342
+
343
+ end
344
+
345
+ end
346
+
347
+
348
+ def read_block_facts module_path, method_name, grp_sym, key_sym, key_val
349
+
350
+ # -- ---------------------------------------------------------- -- #
351
+ # -- Derive name of block db ini file using id and method name. -- #
352
+ # -- ---------------------------------------------------------- -- #
353
+ block_filepath = FactLocator.block_factdb_path module_path, method_name
354
+ Throw.if_not_exists block_filepath
355
+
356
+ # -- ----------------------------------------------------------- -- #
357
+ # -- Initialize block database building upon the wider scoped @e -- #
358
+ # -- ----------------------------------------------------------- -- #
359
+ FactReader.new @c, block_filepath, grp_sym, key_sym, key_val
360
+
361
+ end
362
+
363
+
364
+ end