Class: CmdLine

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/opensecret/commons/eco.cmdline.rb

Overview

– ——————————————————————————— – # – The [Command Interpreter] – # – ——————————————————————————— – # – – # – From the command line we receive the below asset groups. – # – – # – [1] - major use case commands like “create”, “register”, “destroy” – # – [2] - specifiers telling us “create what”, “destroy which ones” – # – [3] - boolean flags that dictate which way the hammer should fall – # – [4] - option / arg config pairs (options can be long or short) – # – – # – Some flags and options are mandatory - others are optional. Argument types – # – are usually => [ booleans, strings, lists, sets or numbers ]. – # – – # – ——————————————————————————— – # – Art or Science – # – ——————————————————————————— – # – – # – Parsing the command line and returning concise error messages is much more – # – [ART] than it is [SCIENCE]. This is because the permutations and combinations – # – are mind bogglingly vast. Hence this code is strictly [“best efforts”]. – # – – # – That said, the invoked commands should be belt and braces in processing the – # – arguments and switches provided on the command line. – # – – # – This command interpreter in no way absolves the evoked software from the legwork – # – of security, validation and semantic assessments. – # – – # – ——————————————————————————— – #

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCmdLine

Returns a new instance of CmdLine.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/opensecret/commons/eco.cmdline.rb', line 46

def initialize

  # -- ----------------------------------------------------------- --- #
  # -- If no commands to interpret - assume the caller needs help. --- #
  # -- ----------------------------------------------------------- --- #
  ARGV.push "--help" if ARGV.length == 0

  @key_values = {}
  @args_cache = [].replace ARGV

  # --- ------------------------------------------------------------- --- #
  # --- [--help] is a peripheral command with no [do] [what] pattern. --- #
  # --- ------------------------------------------------------------- --- #
  print_help_screen       if ARGV.include? "--help"
  print_help_screen       if ARGV.include? "-h"

  # --- -------------------------------------------------- --- #
  # --- Each line below pertains to a [do] [what] command. --- #
  # --- -------------------------------------------------- --- #
  read_eco_create_args     if command_matches? "create", "what", "w"
  read_read_db_names_args  if command_matches? "read", "s3", "s"
  read_aws_register_args   if command_matches? "register", "aws-user", "a"
  read_destroy_app_args    if command_matches? "destroy", "app", "a"
  read_task_args           if command_matches? "task", "what", "w"

  # --- --------------------------------------------------------- --- #
  # --- Notify caller if [do] [what] portion could not be mapped. --- #
  # --- --------------------------------------------------------- --- #
  handle_cmd_match_fail  if @options_parser == nil

  begin

    @options_parser.parse!
    @args_after = ARGV

    missing_args = @mandatory_options.select{ |param| @key_values[param].nil? }
    unless missing_args.empty?
      raise OptionParser::MissingArgument.new(missing_args.join(', '))
    end

  rescue OptionParser::InvalidOption => exception

    log.warn(ere) { "#--- ---------------------------------------------- --- #" }
    log.warn(ere) { "#--- eco did not recognize a command option.        --- #" }
    log.warn(ere) { "#--- ---------------------------------------------- --- #" }
    log.warn(ere) { "#--- #{exception}" }
    log.warn(ere) { "#--- #{exception.inspect}" }

#### Fix this if too spurious
#### Fix this if too spurious
#### Fix this if too spurious
#### Fix this if too spurious
################      puts exception.backtrace if @@VERBOSE_MODE

    log.warn(ere) { "#{exception.backtrace}" } ##### may be add if ARGV.include? "--debug"
    log.warn(ere) { @options_parser.help }
    log.warn(ere) { "#--- ---------------------------------------------- --- #" }

    # @@
    # @@ No need to exit from this - this script does not need
    # @@ to be hard-coded with every command line option.
    # @@ (We need only know the [Mandatory] ones which is
    # @@ handled by the below rescue block.
    # @@

##################  DELETE ME ASAP
##############      exit
##################  DELETE ME ASAP


  rescue OptionParser::MissingArgument => missing_arg

    log.fatal(ere) { $!.to_s }
    log.fatal(ere) { @options_parser }
    exit

  end

end

Instance Attribute Details

#args_afterObject (readonly)

Returns the value of attribute args_after.



43
44
45
# File 'lib/opensecret/commons/eco.cmdline.rb', line 43

def args_after
  @args_after
end

#args_cacheObject (readonly)

Returns the value of attribute args_cache.



42
43
44
# File 'lib/opensecret/commons/eco.cmdline.rb', line 42

def args_cache
  @args_cache
end

#createObject (readonly)

Returns the value of attribute create.



35
36
37
# File 'lib/opensecret/commons/eco.cmdline.rb', line 35

def create
  @create
end

#do_destroy_appObject (readonly)

Returns the value of attribute do_destroy_app.



39
40
41
# File 'lib/opensecret/commons/eco.cmdline.rb', line 39

def do_destroy_app
  @do_destroy_app
end

#do_read_db_namesObject (readonly)

Returns the value of attribute do_read_db_names.



37
38
39
# File 'lib/opensecret/commons/eco.cmdline.rb', line 37

def do_read_db_names
  @do_read_db_names
end

#do_register_userObject (readonly)

Returns the value of attribute do_register_user.



38
39
40
# File 'lib/opensecret/commons/eco.cmdline.rb', line 38

def do_register_user
  @do_register_user
end

#key_valuesObject (readonly)

Returns the value of attribute key_values.



41
42
43
# File 'lib/opensecret/commons/eco.cmdline.rb', line 41

def key_values
  @key_values
end

#taskObject (readonly)

Returns the value of attribute task.



36
37
38
# File 'lib/opensecret/commons/eco.cmdline.rb', line 36

def task
  @task
end

Class Method Details

.has?(a_string) ⇒ Boolean

– – Returns true if the option text was included on the command line. – – This method does not look within a list of values. Only call this – method if the text is a free form switch WITHOUT an equal sign. –

Returns:

  • (Boolean)


133
134
135
# File 'lib/opensecret/commons/eco.cmdline.rb', line 133

def self.has? a_string
  return CmdLine.instance.args_cache.include? a_string
end

.include?(a_symbol) ⇒ Boolean

– – Return true if symbol (switch) was included on the command line. – – WARNING - Do not use externally as the line is cleared. – - Call has? like =] if CmdLine.has? –debug –

Returns:

  • (Boolean)


144
145
146
# File 'lib/opensecret/commons/eco.cmdline.rb', line 144

def self.include? a_symbol
  return CmdLine.instance.key_values.include? a_symbol
end

Instance Method Details

#command_matches?(cmd_str, flag_long, flag_short) ⇒ Boolean

– —————————————————————————- – # – Does the command line contain a specific command and a flag in either of its – # – forms - long and short. If yes then this method will return true. – # – —————————————————————————- – #

Returns:

  • (Boolean)


153
154
155
156
157
158
# File 'lib/opensecret/commons/eco.cmdline.rb', line 153

def command_matches? cmd_str, flag_long, flag_short

  return ( ARGV.include?( cmd_str ) && ARGV.include?("--#{flag_long}") ) ||
     ( ARGV.include?( cmd_str ) && ARGV.include?("-#{flag_short}") )

end

#handle_cmd_match_failObject

– —————————————————————————- – # – forms - long and short. If yes then this method will return true. – # – —————————————————————————- – #



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/opensecret/commons/eco.cmdline.rb', line 164

def handle_cmd_match_fail

  log.fatal(ere) { "    # - ------------------------------------------------------------ - #" }
  log.fatal(ere) { "    # - eco command ==> could not match == [do] [what] [how] [where] - #" }
  log.fatal(ere) { "    # - ------------------------------------------------------------ - #" }
  log.fatal(ere) { "    eco [do] [what]" }
  log.fatal(ere) { "    Could not match the [do what] branch of the command tree." }
  log.fatal(ere) { "    [do] is CRUD based eg [create, register, read, update, destroy]." }
  log.fatal(ere) { "    The [what] part tells the command interpreter what you want to do." }
  log.fatal(ere) { "    eco optional arguments == [how] [where] [to]" }
  log.fatal(ere) { "    [how]   -   do it how   eg | --clean      | --dry-run |" }
  log.fatal(ere) { "    [where] -   (on what)   eg | --cloud      | --local   |" }
  log.fatal(ere) { "    [to]    -   do it to    eg | --eco-system | --service |" }

  exit

end

— ——————————————————— — ## — How to use Declarative and Dynamic Command Interpretation — ## — ——————————————————— — ##


— Once SREs are familiar with this command interpreter class — the next refactor step is to generate the whole thing dynamically. — I will probably write a ruby gem to do exactly this.


— The essence is to create a JSON or YAML configuration file that — holds the command line interpretation variables. This is used to — dynamically generate the optparse blocks.


— ——————————————————— — ## — How to use Dynamically Generate the Help Screen — ## — ——————————————————— — ##


— To generate the help screen you can loop round calling each — parser block (without any actual cmd line arguments)!


— Then you loop doing a to_string puts opt_parser for each — parser and all the options will be ejected automatically!


— ——————————————————— — ##



396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
# File 'lib/opensecret/commons/eco.cmdline.rb', line 396

def print_help_screen

  read_eco_create_args
  args_documented = @options_parser.to_s
  read_aws_register_args
  args_documented = "#{args_documented}\n\n#{@options_parser.to_s}"
  read_read_db_names_args
  args_documented = "#{args_documented}\n\n#{@options_parser.to_s}"
  read_destroy_app_args
  args_documented = "#{args_documented}\n\n#{@options_parser.to_s}"

  if false then
    log.warn(ere) { "    # --- --------------------------------------------------------------------- --- #" }
    log.warn(ere) { "    # --- create executable  => =>  [only for DevOps and SRE personnel]         --- #" }
    log.warn(ere) { "    # --- --------------------------------------------------------------------- --- #" }

    log.warn(ere) { "        ruby eco-invoke.rb [do] [what]" }
    log.warn(ere) { "        ruby eco-invoke.rb [create] [--exe]" }
    log.warn(ere) { "        ruby eco-invoke.rb create --exe" }
  end

  log.warn(ere) { "    # --- --------------------------------------------------------------------- --- #" }
  log.warn(ere) { "    # --- eco peripheral commands                                               --- #" }
  log.warn(ere) { "    # --- --------------------------------------------------------------------- --- #" }
  log.warn(ere) { "        eco --help" }
  log.warn(ere) { "        eco -h" }
  log.warn(ere) { "    # --- --------------------------------------------------------------------- --- #" }
  log.warn(ere) { "    # --- eco arguments documentation                                           --- #" }
  log.warn(ere) { "    # --- --------------------------------------------------------------------- --- #" }
  log.warn(ere) { args_documented }

  exit

end

#read_aws_register_argsObject

— ——————– — ## — Register an AWS User — ## — ——————– — ##



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/opensecret/commons/eco.cmdline.rb', line 243

def read_aws_register_args

  ## ---------------------------------------------------------- #
  @do_register_user = true
  @mandatory_options = [:aws_user, :aws_user_id, :aws_password]
  ## ---------------------------------------------------------- #
  @options_parser = OptionParser.new do | the_options |

    the_options.banner = "    eco register --aws-user   => options to register [aws credentials]\n\n"

    the_options.on( "-a", "--aws-user", "Registering AWS Credentials") do

      @key_values[:aws_user] = true

    end

    the_options.on( "-u", "--aws-user-id AWS_USER_ID", "Your AWS User ID Key (mandatory)") do | aws_user_id |

      @key_values[:aws_user_id] = aws_user_id

    end

    the_options.on( "-p", "--aws-password AWS_PASSWORD", "Your AWS User Password (mandatory)") do | aws_password |

      @key_values[:aws_password] = aws_password

    end

  end

end

#read_destroy_app_argsObject

— ——————————————————– — ## — Destroy and reclaim resources from created applications. — ## — ——————————————————– — ##



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/opensecret/commons/eco.cmdline.rb', line 345

def read_destroy_app_args

  ## ---------------------------------------------------------- #
  @do_destroy_app = true
  @mandatory_options = [:destroy_app, :key]
  ## ---------------------------------------------------------- #
  @options_parser = OptionParser.new do | the_options |

    the_options.banner = "    eco destroy --app   => destroying an eco system\n\n"

    the_options.on( "-a", "--app", "Destroy enterprise application") do

      @key_values[:destroy_app] = true

    end

    the_options.on( "-k", "--key APP_KEY", "Key (ref) of app to delete (mandatory)") do | key_value |

      @key_values[:key] = key_value

    end

  end

end

#read_eco_create_argsObject

— ———————- — ## — Create the application — ## — ———————- — ##



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/opensecret/commons/eco.cmdline.rb', line 213

def read_eco_create_args

  ## ---------------------------------------------------------- #
  @create = true
  @mandatory_options = [:service_descriptors]
  ## ---------------------------------------------------------- #
  @options_parser = OptionParser.new do | the_options |

    the_options.banner = "    eco create --what   => create which eco systems\n\n"

##      the_options.on( "-f", "--versions-file FILE_PATH", "Service versions file in JSON (mandatory)") do | versions_file |

##        @key_values[:versions_file] = versions_file

##      end

    the_options.on( "-w", "--what mongo,email,...", Array, "Comma separated service descriptors (mandatory)") do | service_descriptors_list |

      @key_values[:service_descriptors] = service_descriptors_list

    end

  end

end

#read_read_db_names_argsObject

— ————————– — ## — Read the DB Name Arguments — ## — ————————– — ##



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/opensecret/commons/eco.cmdline.rb', line 321

def read_read_db_names_args

  ## ---------------------------------------------------------- #
  @do_read_db_names = true
  @mandatory_options = [:read_db_names]
  ## ---------------------------------------------------------- #
  @options_parser = OptionParser.new do | the_options |

    the_options.banner = "    eco read --s3   => reading names of customer databases in S3\n\n"

    the_options.on( "-s", "--s3", "Available Customer DBs in S3") do

      @key_values[:read_db_names] = true

    end

  end

end

#read_task_argsObject

– – Task does something (encrypts or decrypts) some text. – – main command => encrypt – mandatory arg => –text=abc123 or -t – –



283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/opensecret/commons/eco.cmdline.rb', line 283

def read_task_args

  ## ------------------------------------------------------------------ #
  @task = true
  @mandatory_options = [:service_descriptors]
  ## ------------------------------------------------------------------ #
  @options_parser = OptionParser.new do | the_options |

    the_options.banner = "    eco encrypt --text   => options to encrypt [some text]\n\n"


    the_options.on( "-w", "--what mongo,email,...", Array, "Comma separated descriptors (mandatory)") do | service_descriptors_list |

      @key_values[:service_descriptors] = service_descriptors_list

    end


    the_options.on( "-n", "--name NAME", "The name (reference) of the encryptee.") do | name |

      @key_values[:name] = name

    end

    the_options.on( "-f", "--file FILE", "The name of the file whose text is to be decrypted") do | file |

      @key_values[:file] = file

    end

  end

end