Module: Ncio::Support::OptionParsing
- Included in:
- App
- Defined in:
- lib/ncio/support/option_parsing.rb
Overview
Support methods intended to be mixed into the application class. These methods are specific to command line parsing. The model is [GLOBAL OPTIONS] SUBCOMMAND [SUBCOMMAND OPTIONS]
Configuration state parsed from options is intended to be stored in a
Constant Summary collapse
- BANNER =
<<-'EOBANNER'.freeze usage: ncio [GLOBAL OPTIONS] SUBCOMMAND [ARGS] Sub Commands: backup Backup Node Classification resources restore Restore Node Classification resources transform Transform a backup, replacing hostnames Quick Start: On the host of the Node Classifier service, as root or pe-puppet (to read certs and keys) /opt/puppetlabs/puppet/bin/ncio backup > groups.$(date +%s).json /opt/puppetlabs/puppet/bin/ncio restore < groups.1467151827.json Transformation: ncio --uri https://master1.puppet.vm:4433/classification-api/v1 backup \ | ncio transform --hostname master1.puppet.vm:master2.puppet.vm \ | ncio --uri https://master2.puppet.vm:4433/classification-api/v1 restore Global options: (Note, command line arguments supersede ENV vars in {}'s) EOBANNER
- NAMES =
Names used to look for the default client certificate
[Socket.gethostname.downcase, 'pe-internal-orchestrator']
- SSLDIR =
'/etc/puppetlabs/puppet/ssl'.freeze
- CERT_MSG =
'White listed client SSL cert {NCIO_CERT} '\ 'See: https://goo.gl/zCjncC'.freeze
- KEY_MSG =
'Client RSA key, must match certificate '\ '{NCIO_KEY}'.freeze
- CACERT_MSG =
'CA Cert to authenticate the service uri '\ '{NCIO_CACERT}'.freeze
- CACERT_DEFAULT =
(SSLDIR + '/certs/ca.pem').freeze
- FILE_DEFAULT_MAP =
Map is indexed by the subcommand
{ 'backup' => 'STDOUT', 'restore' => 'STDIN' }.freeze
- CONNECT_TIMEOUT_DEFAULT =
120
Instance Attribute Summary collapse
-
#argv ⇒ Object
readonly
Returns the value of attribute argv.
-
#env ⇒ Object
readonly
Returns the value of attribute env.
-
#opts ⇒ Object
readonly
Returns the value of attribute opts.
Class Method Summary collapse
Instance Method Summary collapse
- #cert_default ⇒ Object
- #certname ⇒ Object
- #key_default ⇒ Object
-
#map_hostnames(hostnames) ⇒ Hash<String, String>
Map an array of hostnames separated by a colon.
-
#parse_global_options!(argv, env) ⇒ Hash<Symbol, String>
Parse out the global options, the ones specified between the main executable and the subcommand argument.
-
#parse_options(argv, env) ⇒ Hash<Symbol, String>
Parse options using the argument vector and the environment hash as input.
-
#parse_subcommand!(argv) ⇒ String
Extract the subcommand, if any, from the arguments provided.
-
#parse_subcommand_options!(subcommand, argv, env) ⇒ Hash<Symbol, String>
Parse the subcommand options.
-
#reset_options! ⇒ Hash<Symbol, String>
Reset the @opts instance variable by parsing @argv and @env.
Instance Attribute Details
#argv ⇒ Object (readonly)
Returns the value of attribute argv.
15 16 17 |
# File 'lib/ncio/support/option_parsing.rb', line 15 def argv @argv end |
#env ⇒ Object (readonly)
Returns the value of attribute env.
15 16 17 |
# File 'lib/ncio/support/option_parsing.rb', line 15 def env @env end |
#opts ⇒ Object (readonly)
Returns the value of attribute opts.
15 16 17 |
# File 'lib/ncio/support/option_parsing.rb', line 15 def opts @opts end |
Class Method Details
.pem_exists?(name) ⇒ Boolean
172 173 174 |
# File 'lib/ncio/support/option_parsing.rb', line 172 def self.pem_exists?(name) File.exist?(SSLDIR + "/certs/#{name}.pem") end |
Instance Method Details
#cert_default ⇒ Object
180 181 182 |
# File 'lib/ncio/support/option_parsing.rb', line 180 def cert_default SSLDIR + "/certs/#{certname}.pem" end |
#certname ⇒ Object
176 177 178 |
# File 'lib/ncio/support/option_parsing.rb', line 176 def certname NAMES.find { |n| Ncio::Support::OptionParsing.pem_exists?(n) } || NAMES.first end |
#key_default ⇒ Object
184 185 186 |
# File 'lib/ncio/support/option_parsing.rb', line 184 def key_default SSLDIR + "/private_keys/#{certname}.pem" end |
#map_hostnames(hostnames) ⇒ Hash<String, String>
Map an array of hostnames separated by a colon. The left is the key of the map, the right is the value. The Hash returned is "smart" in that a key that does not exist will return a value matching the key.
163 164 165 166 167 168 169 170 |
# File 'lib/ncio/support/option_parsing.rb', line 163 def map_hostnames(hostnames) smart_map = Hash.new { |_, key| key } hostnames.each_with_object(smart_map) do |pair, hsh| (k, v) = pair.split(':') hsh[k] = v hsh end end |
#parse_global_options!(argv, env) ⇒ Hash<Symbol, String>
Parse out the global options, the ones specified between the main executable and the subcommand argument.
Modifies argv as a side effect, shifting elements from the array until the first unknown option is found, which is assumed to be the subcommand name.
rubocop:disable Metrics/MethodLength, Metrics/AbcSize
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 |
# File 'lib/ncio/support/option_parsing.rb', line 59 def (argv, env) semver = Ncio::VERSION host = Socket.gethostname cert_default = self.cert_default key_default = self.key_default Ncio::Trollop.(argv) do stop_on_unknown version "ncio #{semver} (c) 2016 Jeff McCune" BANNER uri_dfl = env['NCIO_URI'] || "https://#{host}:4433/classifier-api/v1" opt :uri, 'Node Classifier service uri '\ '{NCIO_URI}', default: uri_dfl opt :cert, CERT_MSG, default: env['NCIO_CERT'] || cert_default opt :key, KEY_MSG, default: env['NCIO_KEY'] || key_default opt :cacert, CACERT_MSG, default: env['NCIO_CACERT'] || CACERT_DEFAULT log_msg = 'Log file to write to or keywords '\ 'STDOUT, STDERR {NCIO_LOGTO}' opt :logto, log_msg, default: env['NCIO_LOGTO'] || 'STDERR' opt :syslog, 'Log to syslog', default: true, conflicts: :logto opt :verbose, 'Set log level to INFO' opt :debug, 'Set log level to DEBUG' opt :retry_connections, 'Retry API connections, '\ 'e.g. waiting for the service to come online. '\ '{NCIO_RETRY_CONNECTIONS}', default: (env['NCIO_RETRY_CONNECTIONS'] == 'true') || false opt :connect_timeout, 'Retry <i> seconds if --retry-connections=true '\ '{NCIO_CONNECT_TIMEOUT}', default: env['NCIO_CONNECT_TIMEOUT'] || CONNECT_TIMEOUT_DEFAULT end end |
#parse_options(argv, env) ⇒ Hash<Symbol, String>
Parse options using the argument vector and the environment hash as input. Option parsing occurs in two phases, first the global options are parsed. These are the options specified before the subcommand. The subcommand, if any, is matched, and subcommand specific options are then parsed from the remainder of the argument vector.
39 40 41 42 43 44 45 46 47 |
# File 'lib/ncio/support/option_parsing.rb', line 39 def (argv, env) argv_copy = argv.dup opts = (argv_copy, env) subcommand = parse_subcommand!(argv_copy) opts[:subcommand] = subcommand sub_opts = (subcommand, argv_copy, env) opts.merge!(sub_opts) opts end |
#parse_subcommand!(argv) ⇒ String
Extract the subcommand, if any, from the arguments provided. Modifies argv as a side effect, shifting the subcommand name if it is present.
97 98 99 |
# File 'lib/ncio/support/option_parsing.rb', line 97 def parse_subcommand!(argv) argv.shift || false end |
#parse_subcommand_options!(subcommand, argv, env) ⇒ Hash<Symbol, String>
Parse the subcommand options. This method branches out because each subcommand can have quite different options, unlike global options which are consistent across all invocations of the application.
Modifies argv as a side effect, shifting all options as things are parsed.
rubocop:disable Metrics/MethodLength, Metrics/AbcSize
111 112 113 114 115 116 117 118 119 120 121 122 123 124 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 |
# File 'lib/ncio/support/option_parsing.rb', line 111 def (subcommand, argv, env) case subcommand when 'backup', 'restore' Ncio::Trollop.(argv) do "Node Classification #{subcommand} options:" groups_msg = 'Operate against NC groups. See: https://goo.gl/QD6ZdW' opt :groups, groups_msg, default: true file_msg = 'File to operate against {NCIO_FILE} or STDOUT, STDERR' file_default = FILE_DEFAULT_MAP[subcommand] opt :file, file_msg, default: env['NCIO_FILE'] || file_default end when 'transform' opts = Ncio::Trollop.(argv) do "Node Classification transformations\n"\ 'Note: Currently only Monolithic (All-in-one) deployments are '\ "supported.\n\nTransformation matches against class names "\ 'assigned to groups. Transformation of hostnames happen '\ 'against rules assigned to groups and class parameters for '\ "matching classes.\n\nOptions:" hostname_msg = 'Replace the fully qualified domain name on the '\ 'left with the right, separated with a : '\ 'e.g --hostname master1.acme.com:master2.acme.com' opt :class_matcher, 'Regexp matching classes assigned to groups. '\ 'Passed to Regexp.new()', default: '^puppet_enterprise' opt :input, 'Input file path or keywords STDIN, STDOUT, STDERR', default: 'STDIN' opt :output, 'Output file path or keywords STDIN, STDOUT, STDERR', default: 'STDOUT' opt :hostname, hostname_msg, type: :strings, multi: true, required: true end opts[:matcher] = Regexp.new(opts[:class_matcher]) if opts[:hostname_given] hsh = map_hostnames(opts[:hostname].flatten) opts.merge!(hostname_map: hsh) end else Ncio::Trollop.die "Unknown subcommand: #{subcommand.inspect}" end end |
#reset_options! ⇒ Hash<Symbol, String>
Reset the @opts instance variable by parsing @argv and @env. Operates against duplicate copies of the argument vector avoid side effects.
22 23 24 |
# File 'lib/ncio/support/option_parsing.rb', line 22 def @opts = (argv, env) end |