Class: CLI

Inherits:
Thor
  • Object
show all
Defined in:
lib/cli.rb

Overview

This command line processor extends the Thor gem CLI tools in order to

  • read the posted commands, options and switches

  • maps the incoming string data to objects

  • assert that the mandatory options exist

  • assert the type of each parameter

  • ensure that the parameter values are in range

  • delegate processing to the registered handlers

Instance Method Summary collapse

Instance Method Details

#commitObject

The commit use case commits any changes made to the safe book into master. This is straightforward if the master’s state has not been forwarded by a ckeckin from another (shell) branch.



286
287
288
289
# File 'lib/cli.rb', line 286

def commit
  log.info(x) { "commit (save) any changes made to this branch into the master." }
  SafeDb::Commit.new.flow()
end

#copy(line = nil) ⇒ Object

Copy into the clipboard the value held by the named line at the current book’s open chapter and verse.

This is more accurate and more secure than echoing the password and then performing a SELECT then COPY and then PASTE.

Use safe clear to wipe (overwrite) the sensitive value in the clipboard.

Parameters:

  • line (String) (defaults to: nil)

    the name of the line whose data will be copied. If no line is given the default @password is assumed.



172
173
174
175
176
177
# File 'lib/cli.rb', line 172

def copy( line = nil )
  log.info(x) { "copy the line value at the current chpater/verse into the clipboard." }
  copy_uc = SafeDb::Copy.new
  copy_uc.line = line
  copy_uc.flow()
end

#diffObject

The diff use case spells out the key differences between the safe book on the master line the one on the current working branch.

By default when conflicts occur, priority is given to the current working branch. No parameters are required to perform a diff.



273
274
275
276
# File 'lib/cli.rb', line 273

def diff
  log.info(x) { "prophesy list of either refresh or commit actions." }
  SafeDb::Diff.new().flow()
end

#docker(command = "login") ⇒ Object

This docker use case .…

safe docker 
safe docker logout

Parameters:

  • command (String) (defaults to: "login")

    the action to be taken which is currently limited to either login or logout



685
686
687
688
689
690
691
692
# File 'lib/cli.rb', line 685

def docker( command = "login" )

  log.info(x) { "request to #{command} into or out of a docker repository." }
  docker_uc = SafeDb::Docker.new
  docker_uc.command = command
  docker_uc.flow()

end

#exportObject

Export one, some or all chapters, verses and lines within the logged in book. The –print flag demands that the exported text goes to stdout otherwise it will be placed in an aptly named file in the present working directory.



312
313
314
315
# File 'lib/cli.rb', line 312

def export
  log.info(x) { "export book chapter content or dictionary at verse in JSON format." }
  SafeDb::Export.new.flow()
end

#generate(line = "@password") ⇒ Object

The generate use case generates a random string credential that abides by the laws set out by configured and/or default parameter properties. These properties include the character superset to which all credential characters belong, the median length of the credential and the (give or take) span denoting the shortest and longest possible credentials.

Parameters:

  • line (String) (defaults to: "@password")

    name of line the credential is stored against. Defaults to @password



468
469
470
471
472
473
# File 'lib/cli.rb', line 468

def generate( line = "@password" )
  log.info(x) { "generate a string credential and store it against line [#{line}]." }
  generate_uc = SafeDb::Generate.new()
  generate_uc.line = line
  generate_uc.flow()
end

#gitObject



401
402
403
404
405
406
407
408
# File 'lib/cli.rb', line 401

def git
  log.info(x) { "performing a git repository interaction." }
####    git_uc = SafeDb::Git.new()
#####    remote_uc.provision = true if options[ :provision ]
#####    remote_uc.provision = false unless options[ :provision ]
####    git_uc.flow()
  SafeDb::Git.new().flow()
end

#goto(index) ⇒ Object

Goto is a shortcut (or alias even) for the open command that takes an integer index that effectively specifies which <envelope> and <key> to open.

Parameters:

  • index (Number)

    the integer index chosen from the list procured by the view command.



592
593
594
595
596
597
598
# File 'lib/cli.rb', line 592

def goto index
  log.info(x) { "opens the chapter and verse at index [#{index}]." }
  goto_uc = SafeDb::Goto.new
  goto_uc.index = index
  goto_uc.flow()

end

#idObject

Put out the multiple formats of the current timestamp.



718
719
720
721
722
# File 'lib/cli.rb', line 718

def id
  log.info(x) { "prints out the current timestamp identifiers." }
  id_uc = SafeDb::Id.new
  id_uc.flow()
end

#import(import_filepath) ⇒ Object

The import use case takes a filepath parameter in order to pull in a json formatted data structure.

Parameters:

  • import_filepath (String)

    the path to the JSON file that we will import



325
326
327
328
329
330
# File 'lib/cli.rb', line 325

def import import_filepath
  log.info(x) { "importing into current book from file #{import_filepath}." }
  import_uc = SafeDb::Import.new
  import_uc.import_filepath = import_filepath
  import_uc.flow()    
end

#init(book_name) ⇒ Object

Initialize a safe credentials book with this name and collect the human sourced pasword to be put through key derivation functions.

Parameters:

  • book_name (String)

    the name of the credentials book to be created



95
96
97
98
99
100
101
# File 'lib/cli.rb', line 95

def init( book_name )
  log.info(x) { "initialize a new safe credentials book called [#{book_name}]." }
  init_uc = SafeDb::Init.new
  init_uc.password = options[ :password ] if options[ :password ]
  init_uc.book_name = book_name
  init_uc.flow()
end

#jenkins(command, service, url) ⇒ Object

This Jenkins use case injects for example the AWS IAM user access key, secret key and region key into a running Jenkins CI (Continuous Integration) service at the specified (url) location.

safe jenkins post aws http://localhost:8080

Parameters:

  • command (String)

    the action to be taken which is currently limited to be [post].

  • service (String)

    Which service do the credentials being posted originate from? The crrent list includes

    - aws      ( the 3 IAM user credentials )
    - docker   ( the username / password of docker repository )
    - git      ( the username/password of Git repository )
    - rubygems ( the username / password of RubyGems package manager account )
    
  • url (String)

    the full url of the jenkins service for example localhost:8080 which includes the scheme (http|https) the hostname or ip address and the port jenkins is listening on (if not the default 80 or 443).



659
660
661
662
663
664
665
666
667
668
669
670
# File 'lib/cli.rb', line 659

def jenkins( command, service, url )

  log.info(x) { "request to #{command} #{service} credentials to Jenkins at #{url}" }
  jenkins_uc = SafeDb::Jenkins.new

  jenkins_uc.command = command if command
  jenkins_uc.service = service if service
  jenkins_uc.url     = url     if url

  jenkins_uc.flow()

end

#keys(keypair_name = nil) ⇒ Object

The default action of the keys use case is to create a private and public keypair and store them within the open chapter and verse.

Parameters:

  • keypair_name (String) (defaults to: nil)

    optional name of the keypair (for example gitlab)



514
515
516
517
518
519
520
# File 'lib/cli.rb', line 514

def keys( keypair_name = nil )
  log.info(x) { "Generate an elliptic curve private and public cryptographic keys." }
  log.info(x) { "The keypair name [ #{keypair_name} ] was given." } if keypair_name
  keys_uc = SafeDb::Keys.new
  keys_uc.keypair_name = keypair_name if keypair_name
  keys_uc.flow()
end

#login(book_name = nil) ⇒ Object

Login in order to securely interact with your safe credentials.

Parameters:

  • book_name (String) (defaults to: nil)

    the name of the credentials book to login to



119
120
121
122
123
124
125
126
127
# File 'lib/cli.rb', line 119

def ( book_name = nil )
  log.info(x) { "login attempt to the safe book called [#{book_name}]." }
   = SafeDb::Login.new
  .book_name = book_name unless book_name.nil?
  .password = options[ :password ] if options[ :password ]
  .clip = true if options[ :clip ]
  .clip = false unless options[ :clip ]
  .flow()
end

#obliterateObject

The obliterate command does not need to be secured behind authentication because all it does is delete a directory. Not withstanding taking a backup - this command is exactly like the bash rm -fr command.



432
433
434
435
# File 'lib/cli.rb', line 432

def obliterate
  log.info(x) { "request to obliterate the safedb master database." }
  SafeDb::Obliterate.new().flow()
end

#open(chapter, verse) ⇒ Object

Open up a conduit (path) to the place where we can issue read, create, update, and destroy commands.

The allowed characters that makeup chapter and verse aside from alphanumerics are

  • dollar signs

  • percent signs

  • ampersands

  • hyphens

  • underscores

  • plus signs

  • equal signs

  • @ signs

  • period characters and

  • question marks

Notably whitespace including spaces and tabs are not allowed.

Parameters:

  • chapter (String)

    the chapter of the logged in book to open

  • verse (String)

    the verse of the logged in book and specified chapter to open



253
254
255
256
257
258
259
# File 'lib/cli.rb', line 253

def open chapter, verse
  log.info(x) { "open a chapter and verse to read from or write to." }
  open_uc = SafeDb::Open.new
  open_uc.chapter = chapter
  open_uc.verse = verse
  open_uc.flow()
end

#paste(line = nil) ⇒ Object

Paste the current clipboard or selection text into the specified line at the current book’s open chapter and verse.

Sensitive values now neither need to be put on the commnad line (safe put) or inputted perhaps with a typo when using (safe input).

Use safe wipe to wipe (overwrite) any sensitive values that has been placed on the clipboard.

Parameters:

  • line (String) (defaults to: nil)

    the name of the line that the copied data will be placed alongside. The line either may or may not exist.



195
196
197
198
199
200
# File 'lib/cli.rb', line 195

def paste( line = nil )
  log.info(x) { "paste the line value within the clipboard into the current chpater/verse." }
  paste_uc = SafeDb::Paste.new
  paste_uc.line = line
  paste_uc.flow()
end

Print the value of the specified key belonging to a dictionary at the opened chapter and verse of the currently logged in book.

Parameters:

  • key_name (String)

    the key whose value is to be printed



149
150
151
152
153
154
# File 'lib/cli.rb', line 149

def print key_name
  log.info(x) { "print the key value at the opened chapter and verse." }
  print_uc = SafeDb::Print.new
  print_uc.key_name = key_name
  print_uc.flow()
end

#pushObject

This simple command does not require the user to be logged into a specific book. The only pre-condition is that safe remote –provision has been successfully run thus placing the required remote origin urls.



418
419
420
421
# File 'lib/cli.rb', line 418

def push
  log.info(x) { "request to push safe crypts to the remote backend." }
  SafeDb::Push.new().flow()
end

#put(credential_id, credential_value) ⇒ Object

Put a secret with an id like login/username and a value like joebloggs into the context (eg work/laptop) that was opened with the open command.

Parameters:

  • credential_id (String)

    the id of the secret to put into the opened context

  • credential_value (String)

    the value of the secret to put into the opened context



342
343
344
345
346
347
348
# File 'lib/cli.rb', line 342

def put credential_id, credential_value
  log.info(x) { "put key/value pair into dictionary at open chapter and verse." }
  put_uc = SafeDb::Put.new
  put_uc.credential_id = credential_id
  put_uc.credential_value = credential_value
  put_uc.flow()
end

#read(file_key, file_url) ⇒ Object

The read use case pulls a file in from either an accessible filesystem.

Parameters:

  • file_key (String)

    keyname representing the file that is being read in

  • file_url (String)

    url of file to ingest and assimilate into the safe



531
532
533
534
535
536
537
# File 'lib/cli.rb', line 531

def read file_key, file_url
  log.info(x) { "read file into key #{file_key} from url #{file_url}" }
  read_uc = SafeDb::Read.new
  read_uc.file_key = file_key
  read_uc.file_url = file_url
  read_uc.flow()
end

#refreshObject

The refresh use case commits any changes made to the safe book into master. This is straightforward if the master’s state has not been forwarded by a ckeckin from another (shell) branch.



299
300
301
302
# File 'lib/cli.rb', line 299

def refresh
  log.info(x) { "refresh (update) the working branch with changes from the master." }
  SafeDb::Refresh.new.flow()
end

#remoteObject

Creates remote storage for the safe database crypt files.



361
362
363
364
365
366
367
# File 'lib/cli.rb', line 361

def remote
  log.info(x) { "performing a remote storage use case. The provision flag is set to #{options[ :provision ]}." }
  remote_uc = SafeDb::RemoteGithubToken.new()
  remote_uc.provision = true if options[ :provision ]
  remote_uc.provision = false unless options[ :provision ]
  remote_uc.flow()
end

#remove(line_id) ⇒ Object

The remove use case can remove a single line (key/value pair), or a verse, chapter and even a book

Parameters:

  • line_id (String)

    the ID of the entity to remove (line, verse, chapter or book)



484
485
486
487
488
489
# File 'lib/cli.rb', line 484

def remove line_id
  log.info(x) { "remove a safe entity with a key id [#{line_id}]." }
  remove_uc = SafeDb::Remove.new()
  remove_uc.line_id = line_id
  remove_uc.flow()
end

#rename(now_name, new_name) ⇒ Object

The rename use case can rename an existing chapter, verse or line.

Parameters:

  • now_name (String)

    the existing name of the chapter, verse or line

  • new_name (String)

    the new name the chapter, verse or line goes by



499
500
501
502
503
504
505
# File 'lib/cli.rb', line 499

def rename now_name, new_name
  log.info(x) { "rename the existing chapter, verse or line from [ #{now_name} ] to [ #{new_name} ]." }
  rename_uc = SafeDb::Rename.new()
  rename_uc.now_name = now_name
  rename_uc.new_name = new_name
  rename_uc.flow()
end

#set(directive_name, directive_value) ⇒ Object

The set use case is the generic tool for setting book scoped configuration directives. These directives can only be read, written, updated or removed during a logged in branch.

Parameters:

  • directive_name (String)

    the name of the book-scoped configuration directive

  • directive_value (String)

    the value of the book-scoped configuration directive



448
449
450
451
452
453
454
# File 'lib/cli.rb', line 448

def set directive_name, directive_value
  log.info(x) { "set the configuration directive value for #{directive_name}" }
  set_uc = SafeDb::Set.new
  set_uc.directive_name = directive_name
  set_uc.directive_value = directive_value
  set_uc.flow()
end

#showObject

Show the secrets at the opened path. These secrets are simply written out to the shell console.



564
565
566
567
# File 'lib/cli.rb', line 564

def show
  log.info(x) { "show dictionary at the opened chapter and verse." }
  SafeDb::Show.new.flow()
end

#tellObject

Detail the secret key/value pairs that start with the @ symbol.



135
136
137
138
# File 'lib/cli.rb', line 135

def tell
  log.info(x) { "tell the secret key/value pairs that begin with the @ symbol." }
  SafeDb::Tell.new().flow()
end

#terraform(command = nil) ⇒ Object

This terraform use case exports the AWS IAM user access key, secret key and region key into (very safe) environment variables and then runs terraform plan, apply or destroy.

This is both ultra secure and extremely convenient because the credentials do not leave the safe and exist within (environment variable) memory only for the duration of the terraform command.

It is safe because you do not need to expose your AWS credentials in plain text. It is convenient because switching IAM users and AWS regions is as easy as typing the now ubiquitous safe open command.

safe open <<chapter>> <<verse>>

Parameters:

  • command (String) (defaults to: nil)

    the terraform command to run which is currently limited to plan, apply and destroy. This parameter is optional and if nothing is given then “apply” is assumed.



621
622
623
624
625
626
627
628
# File 'lib/cli.rb', line 621

def terraform( command = nil )
  log.info(x) { "will export IAM credentials then invoke $ terraform #{command}" }
  terraform_uc = SafeDb::Terraform.new
  terraform_uc.command = command if command
  terraform_uc.debug = true if options[ :debug ]
  terraform_uc.debug = false unless options[ :debug ]
  terraform_uc.flow()
end

#tokenObject

Thetoken use cases prints out an encrypted shell token tied to the workstation and shell environment.



209
210
211
212
# File 'lib/cli.rb', line 209

def token
  log.info(x) { "generate and print out an encrypted (shell bound) shell token" }
  SafeDb::Token.new.flow()
end

#versionObject

Printout the version of this safedb.net command line interface. The version should be extracted whether the user types in

  • either safe --version

  • or safe version



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cli.rb', line 70

def version
  log.info(x) { "print the version of this safedb.net personal database." }

  puts ""
  puts "safedb gem version => v#{SafeDb::VERSION}"
  puts "time and date now  => #{SafeDb::TimeStamp.human_readable()}"
  puts "safedb @github.com => https://github.com/devops4me/safedb.net"
  puts "safe @rubygems.org => https://rubygems.org/gems/safedb"
  puts ""

end

#viewObject

Display a bird’s eye view of the domain’s database including its envelopes, their keys and imported objects such as files.



576
577
578
579
580
# File 'lib/cli.rb', line 576

def view
  log.info(x) { "print list of chapter and verse combos to console." }
  view_uc = SafeDb::View.new
  view_uc.flow()
end

#vpn(command = nil) ⇒ Object

This VPN use case connects to the VPN whose specifics are recorded within the vpn.ini factfile living in the same directory as the vpn.rb controlling class.

Parameters:

  • command (String) (defaults to: nil)

    the vpn command to run which is currently limited to up or down This parameter is optional and if nothing is given then “up” is assumed.



705
706
707
708
709
710
# File 'lib/cli.rb', line 705

def vpn( command = nil )
  log.info(x) { "VPN connection command #{command} has been issued." }
  vpn_uc = SafeDb::Vpn.new
  vpn_uc.command = command if command
  vpn_uc.flow()
end

#wipeObject

Thewipe use case clears out any sensitive information from the clipboard.



220
221
222
223
# File 'lib/cli.rb', line 220

def wipe
  log.info(x) { "wipe out any sensitive information from the clipboard." }
  SafeDb::Wipe.new.flow()
end

#write(file_key) ⇒ Object

The write use case writes out a file that was previously ingested and coccooned inside the safe.

Parameters:

  • file_key (String)

    the key name of the file to write out onto the filesystem



548
549
550
551
552
553
554
555
# File 'lib/cli.rb', line 548

def write( file_key )
  log.info(x) { "write out the file against key #{file_key}" }
  log.info(x) { "output folder optionally set to #{options[:to_dir]}" } if options[:to_dir]
  write_uc = SafeDb::Write.new
  write_uc.file_key = file_key
  write_uc.to_dir = options[:to_dir] if options[:to_dir]
  write_uc.flow()
end