Class: WavefrontCliController
- Inherits:
-
Object
- Object
- WavefrontCliController
- Includes:
- WavefrontCli::Constants
- Defined in:
- lib/wavefront-cli/controller.rb
Overview
Dynamically generate a CLI interface from files which describe each subcomand.
Constant Summary
Constants included from WavefrontCli::Constants
WavefrontCli::Constants::ALL_PAGE_SIZE, WavefrontCli::Constants::DEFAULT_CONFIG, WavefrontCli::Constants::DEFAULT_OPTS, WavefrontCli::Constants::EVENT_STATE_DIR, WavefrontCli::Constants::HUMAN_TIME_FORMAT, WavefrontCli::Constants::HUMAN_TIME_FORMAT_MS, WavefrontCli::Constants::SEARCH_SPLIT
Instance Attribute Summary collapse
-
#args ⇒ Object
readonly
Returns the value of attribute args.
-
#cmds ⇒ Object
readonly
Returns the value of attribute cmds.
-
#opts ⇒ Object
readonly
Returns the value of attribute opts.
-
#tw ⇒ Object
readonly
Returns the value of attribute tw.
-
#usage ⇒ Object
readonly
Returns the value of attribute usage.
Instance Method Summary collapse
-
#backtrace_message(err) ⇒ Object
rubocop:enable Metrics/MethodLength rubocop:enable Metrics/AbcSize.
-
#cli_class(cmd, opts) ⇒ Object
Get the CLI class we need to run the command we’ve been given.
-
#default_help ⇒ String
What you see when you do ‘wf –help’ rubocop:disable Metrics/MethodLength.
-
#docopt_hash ⇒ Hash
Command descriptions for docopt.
- #handle_missing_credentials(error) ⇒ Object
-
#import_command(path) ⇒ Object
Load a command description from a file.
-
#initialize(args) ⇒ WavefrontCliController
constructor
A new instance of WavefrontCliController.
- #load_cli_class(cmd, opts) ⇒ Object
-
#load_commands ⇒ Hash
Each command is defined in its own file.
-
#parse_args ⇒ Object
Parse the input.
-
#parse_cmd(cmd) ⇒ Object
Parse a command.
- #parse_opts(options) ⇒ Object
-
#run_command(cli_class_obj) ⇒ Object
rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize.
-
#sanitize_keys(options) ⇒ Object
Symbolize, and remove dashes from option keys.
Constructor Details
#initialize(args) ⇒ WavefrontCliController
Returns a new instance of WavefrontCliController.
32 33 34 35 36 37 38 39 40 |
# File 'lib/wavefront-cli/controller.rb', line 32 def initialize(args) @args = args @cmds = load_commands @usage = docopt_hash cmd, opts = parse_args @opts = parse_opts(opts) cli_class_obj = cli_class(cmd, @opts) run_command(cli_class_obj) end |
Instance Attribute Details
#args ⇒ Object (readonly)
Returns the value of attribute args.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def args @args end |
#cmds ⇒ Object (readonly)
Returns the value of attribute cmds.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def cmds @cmds end |
#opts ⇒ Object (readonly)
Returns the value of attribute opts.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def opts @opts end |
#tw ⇒ Object (readonly)
Returns the value of attribute tw.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def tw @tw end |
#usage ⇒ Object (readonly)
Returns the value of attribute usage.
28 29 30 |
# File 'lib/wavefront-cli/controller.rb', line 28 def usage @usage end |
Instance Method Details
#backtrace_message(err) ⇒ Object
rubocop:enable Metrics/MethodLength rubocop:enable Metrics/AbcSize
186 187 188 189 190 191 192 |
# File 'lib/wavefront-cli/controller.rb', line 186 def (err) if opts[:debug] warn "Backtrace:\n\t#{err.backtrace.join("\n\t")}" else puts "Re-run command with '-D' for backtrace." end end |
#cli_class(cmd, opts) ⇒ Object
Get the CLI class we need to run the command we’ve been given.
108 109 110 111 112 113 114 115 116 |
# File 'lib/wavefront-cli/controller.rb', line 108 def cli_class(cmd, opts) load_cli_class(cmd, opts) rescue WavefrontCli::Exception::UnhandledCommand abort 'Fatal error. Unsupported command. Please open a Github issue.' rescue WavefrontCli::Exception::InvalidInput => e abort "Invalid input. #{e.}" rescue RuntimeError => e abort "Unable to run command. #{e.}." end |
#default_help ⇒ String
What you see when you do ‘wf –help’ rubocop:disable Metrics/MethodLength
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/wavefront-cli/controller.rb', line 46 def default_help s = ['Wavefront CLI', '', 'Usage:', " #{CMD} command [options]", " #{CMD} --version", " #{CMD} --help", '', 'Commands:'] cmds.sort.each do |k, v| s.<< format(' %-18<command>s %<desc>s', command: k, desc: v.description) end s.<< '' s.<< "Use '#{CMD} <command> --help' for further information." s.join("\n") end |
#docopt_hash ⇒ Hash
Returns command descriptions for docopt.
70 71 72 73 74 |
# File 'lib/wavefront-cli/controller.rb', line 70 def docopt_hash cmds.each_with_object(default: default_help) do |(k, v), ret| ret[k.to_sym] = v.docopt end end |
#handle_missing_credentials(error) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/wavefront-cli/controller.rb', line 196 def handle_missing_credentials(error) if DEFAULT_CONFIG.exist? && DEFAULT_CONFIG.file? abort "Credential error. #{error.}" else puts 'No credentials supplied on the command line or via ' \ 'environment variables, and no configuration file found. ' \ "Please run 'wf config setup' to create configuration." .fold(TW, 0) exit 1 end end |
#import_command(path) ⇒ Object
Load a command description from a file. Each is in its own class
return [Class] new class object defining command.
224 225 226 227 228 229 230 |
# File 'lib/wavefront-cli/controller.rb', line 224 def import_command(path) return if path.extname != '.rb' || path.basename.to_s == 'base.rb' k_name = path.basename.to_s[0..-4] require(CMD_DIR + k_name) Object.const_get("WavefrontCommand#{k_name.capitalize}").new end |
#load_cli_class(cmd, opts) ⇒ Object
118 119 120 121 |
# File 'lib/wavefront-cli/controller.rb', line 118 def load_cli_class(cmd, opts) require_relative File.join('.', cmds[cmd].sdk_file) Object.const_get('WavefrontCli').const_get(cmds[cmd].sdk_class).new(opts) end |
#load_commands ⇒ Hash
Each command is defined in its own file. Dynamically load all those commands.
212 213 214 215 216 217 |
# File 'lib/wavefront-cli/controller.rb', line 212 def load_commands CMD_DIR.children.each_with_object({}) do |f, ret| k = import_command(f) ret[k.word.to_sym] = k if k end end |
#parse_args ⇒ Object
Parse the input. The first Docopt.docopt handles the default options, the second works on the command.
79 80 81 82 83 84 85 86 |
# File 'lib/wavefront-cli/controller.rb', line 79 def parse_args Docopt.docopt(usage[:default], version: WF_CLI_VERSION, argv: args) rescue Docopt::Exit => e cmd = args.empty? ? nil : args.first.to_sym abort e. unless usage.key?(cmd) parse_cmd(cmd) end |
#parse_cmd(cmd) ⇒ Object
Parse a command.
91 92 93 94 95 96 97 |
# File 'lib/wavefront-cli/controller.rb', line 91 def parse_cmd(cmd) [cmd, sanitize_keys(Docopt.docopt(usage[cmd], argv: args))] rescue Docopt::DocoptLanguageError => e abort "Mangled command description:\n#{e.}" rescue Docopt::Exit => e abort e. end |
#parse_opts(options) ⇒ Object
99 100 101 |
# File 'lib/wavefront-cli/controller.rb', line 99 def parse_opts() WavefrontCli::OptHandler.new().opts end |
#run_command(cli_class_obj) ⇒ Object
rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/wavefront-cli/controller.rb', line 125 def run_command(cli_class_obj) cli_class_obj.validate_opts cli_class_obj.run rescue Interrupt abort "\nOperation aborted at user request." rescue WavefrontCli::Exception::ConfigFileNotFound => e abort "Configuration file #{e}' not found." rescue WavefrontCli::Exception::CredentialError => e handle_missing_credentials(e) rescue WavefrontCli::Exception::MandatoryValue abort 'A value must be supplied.' rescue Wavefront::Exception::NetworkTimeout abort 'Connection timed out.' rescue Wavefront::Exception::InvalidPermission => e abort "'#{e}' is not a valid privilege." rescue Wavefront::Exception::InvalidUserGroupId => e abort "'#{e}' is not a valid user group id." rescue WavefrontCli::Exception::InvalidValue => e abort "Invalid value for #{e}." rescue WavefrontCli::Exception::ProfileExists => e abort "Profile '#{e}' already exists." rescue WavefrontCli::Exception::ProfileNotFound => e abort "Profile '#{e}' not found." rescue WavefrontCli::Exception::FileNotFound abort 'File not found.' rescue WavefrontCli::Exception::InsufficientData => e abort "Insufficient data. #{e.}" rescue WavefrontCli::Exception::InvalidQuery => e abort "Invalid query. API message: '#{e.}'." rescue WavefrontCli::Exception::SystemError => e abort "Host system error. #{e.}" rescue WavefrontCli::Exception::UnparseableInput => e abort "Cannot parse input. #{e.}" rescue WavefrontCli::Exception::UnparseableSearchPattern abort 'Searches require a key, a value, and a match operator.' rescue WavefrontCli::Exception::UnsupportedFileFormat abort 'Unsupported file format.' rescue WavefrontCli::Exception::UnsupportedOperation => e abort "Unsupported operation.\n#{e.}" rescue WavefrontCli::Exception::UnsupportedOutput => e abort e. rescue WavefrontCli::Exception::UnsupportedNoop abort 'Multiple API call operations cannot be performed as no-ops.' rescue WavefrontCli::Exception::UserGroupNotFound => e abort "Cannot find user group '#{e.}'." rescue Wavefront::Exception::UnsupportedWriter => e abort "Unsupported writer '#{e.}'." rescue WavefrontCli::Exception::UserError => e abort "User error: #{e.}." rescue WavefrontCli::Exception::ImpossibleSearch abort 'Search on non-existent key. Please use a top-level field.' rescue Wavefront::Exception::InvalidSamplingValue abort 'Sampling rates must be between 0 and 0.05.' rescue StandardError => e warn "general error: #{e}" (e) abort end |
#sanitize_keys(options) ⇒ Object
Symbolize, and remove dashes from option keys
return [Hash] h with modified keys
237 238 239 240 241 |
# File 'lib/wavefront-cli/controller.rb', line 237 def sanitize_keys() .each_with_object({}) do |(k, v), r| r[k.to_s.delete('-').to_sym] = v end end |