Class: Collins::CLI::Find
- Inherits:
-
Object
- Object
- Collins::CLI::Find
- Defined in:
- lib/collins/cli/find.rb
Constant Summary collapse
- PROG_NAME =
'collins find'
- QUERY_DEFAULTS =
{ :remoteLookup => false, :operation => 'AND', :size => 100, }
- OPTION_DEFAULTS =
{ :format => :table, # how to display the results :separator => "\t", :attributes => {}, # additional attributes to query for :columns => [:tag, :hostname, :nodeclass, :status, :pool, :primary_role, :secondary_role], :column_override => [], # if set, these are the columns to display :timeout => 120, :show_header => false, # if the header for columns should be displayed :config => nil # collins config to give to setup_client }
Constants included from Formatter
Collins::CLI::Formatter::ADDRESS_POOL_COLUMNS, Collins::CLI::Formatter::FORMATTING_DEFAULTS, Collins::CLI::Formatter::STATUS_STATE_COLUMNS
Constants included from Mixins
Mixins::COLORS, Mixins::ERROR, Mixins::SUCCESS
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#parser ⇒ Object
readonly
Returns the value of attribute parser.
-
#query_opts ⇒ Object
readonly
Returns the value of attribute query_opts.
-
#search_attrs ⇒ Object
readonly
Returns the value of attribute search_attrs.
Instance Method Summary collapse
-
#initialize ⇒ Find
constructor
A new instance of Find.
- #parse!(argv = ARGV) ⇒ Object
- #run! ⇒ Object
- #validate! ⇒ Object
Methods included from Formatter
#display_as_link, #display_as_robot_talk, #display_as_table, #format_assets, #format_pools, #format_states
Methods included from Mixins
#api_call, #as_query?, #collins, #convert_to_query
Constructor Details
#initialize ⇒ Find
Returns a new instance of Find.
30 31 32 33 34 35 36 |
# File 'lib/collins/cli/find.rb', line 30 def initialize @parsed, @validated = false, false @query_opts = QUERY_DEFAULTS.clone @search_attrs = {} @options = OPTION_DEFAULTS.clone @parser = nil end |
Instance Attribute Details
#options ⇒ Object (readonly)
Returns the value of attribute options.
28 29 30 |
# File 'lib/collins/cli/find.rb', line 28 def @options end |
#parser ⇒ Object (readonly)
Returns the value of attribute parser.
28 29 30 |
# File 'lib/collins/cli/find.rb', line 28 def parser @parser end |
#query_opts ⇒ Object (readonly)
Returns the value of attribute query_opts.
28 29 30 |
# File 'lib/collins/cli/find.rb', line 28 def query_opts @query_opts end |
#search_attrs ⇒ Object (readonly)
Returns the value of attribute search_attrs.
28 29 30 |
# File 'lib/collins/cli/find.rb', line 28 def search_attrs @search_attrs end |
Instance Method Details
#parse!(argv = ARGV) ⇒ Object
38 39 40 41 42 43 44 45 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 |
# File 'lib/collins/cli/find.rb', line 38 def parse!(argv = ARGV) raise "See --help for #{PROG_NAME} usage" if argv.empty? @parser = OptionParser.new do |opts| opts. = "Usage: #{PROG_NAME} [options] [hostnamepattern]" opts.separator "Query options:" opts.on('-t','--tag TAG[,...]',Array, "Assets with tag[s] TAG") {|v| search_attrs[:tag] = v} opts.on('-Z','--remote-lookup',"Query remote datacenters for asset (Default: #{query_opts[:remoteLookup]})") {|v| search_attrs[:remoteLookup] = v} opts.on('-T','--type TYPE',String, "Only show assets with type TYPE") {|v| search_attrs[:type] = v} opts.on('-n','--nodeclass NODECLASS[,...]',Array, "Assets in nodeclass NODECLASS") {|v| search_attrs[:nodeclass] = v} opts.on('-p','--pool POOL[,...]',Array, "Assets in pool POOL") {|v| search_attrs[:pool] = v} opts.on('-s','--size SIZE',Integer, "Number of assets to return per page (Default: #{query_opts[:size]})") {|v| query_opts[:size] = v} opts.on('--limit NUM', Integer, "Limit total results to NUM of assets") { |v| [:limit] = v} opts.on('-r','--role ROLE[,...]',Array,"Assets in primary role ROLE") {|v| search_attrs[:primary_role] = v} opts.on('-R','--secondary-role ROLE[,...]',Array,"Assets in secondary role ROLE") {|v| search_attrs[:secondary_role] = v} opts.on('-i','--ip-address IP[,...]',Array,"Assets with IP address[es]") {|v| search_attrs[:ip_address] = v} opts.on('-S','--status STATUS[:STATE][,...]',Array,"Asset status (and optional state after :)") do |v| # in order to know what state was paired with what status, lets store the original params # so the query constructor can create the correct CQL query [:status_state] = v search_attrs[:status], search_attrs[:state] = v.inject([[],[]]) do |memo,s| status,state = s.split(':') memo[0] << status.upcase if not status.nil? and not status.empty? memo[1] << state.upcase if not state.nil? and not state.empty? memo end end opts.on('-a','--attribute attribute[:value[,...]]',String,"Arbitrary attributes and values to match in query. : between key and value") do |x| x.split(',').each do |p| a,v = p.split(':', 2) # attribute:value where value might contain :s a = a.to_sym if not search_attrs[a].nil? and not search_attrs[a].is_a? Array # its a single value, turn it into an array search_attrs[a] = [search_attrs[a]] end if search_attrs[a].is_a? Array # already multivalue, append search_attrs[a] << v else search_attrs[a] = v end end end opts.separator "" opts.separator "Table formatting:" opts.on('-H','--show-header',"Show header fields in output") {[:show_header] = true} opts.on('-c','--columns ATTRIBUTES',Array,"Attributes to output as columns, comma separated (Default: #{[:columns].map(&:to_s).join(',')})") {|v| [:column_override] = v.map(&:to_sym)} opts.on('-x','--extra-columns ATTRIBUTES',Array,"Show these columns in addition to the default columns, comma separated") {|v| [:columns].push(v.map(&:to_sym)).flatten! } opts.on('-f','--field-separator SEPARATOR',String,"Separator between columns in output (Default: #{[:separator]})") {|v| [:separator] = v} opts.separator "" opts.separator "Robot formatting:" opts.on('-l','--link',"Output link to assets found in web UI") {[:format] = :link} opts.on('-j','--json',"Output results in JSON (NOTE: This probably wont be what you expected)") {[:format] = :json} opts.on('-y','--yaml',"Output results in YAML") {[:format] = :yaml} opts.separator "" opts.separator "Extra options:" opts.on('--timeout SECONDS',Integer,"Timeout in seconds (0 == forever)") {|v| [:timeout] = v} opts.on('-C','--config CONFIG',String,'Use specific Collins config yaml for Collins::Client') {|v| [:config] = v} opts.on('-h','--help',"Help") {[:mode] = :help} opts.separator "" opts.separator <<_EXAMPLES_ Examples: Query for devnodes in DEVEL pool that are VMs #{PROG_NAME} -n develnode -p DEVEL Query for asset 001234, and show its system_password #{PROG_NAME} -t 001234 -x system_password Query for all decommissioned VM assets #{PROG_NAME} -a is_vm:true -S decommissioned Query for hosts matching hostname '^web6-' #{PROG_NAME} ^web6- Query for all develnode6 nodes with a value for PUPPET_SERVER #{PROG_NAME} -n develnode6 -a puppet_server -H _EXAMPLES_ end @parser.parse!(argv) # hostname is the final option, no flags search_attrs[:hostname] = argv.shift @parsed = true self end |
#run! ⇒ Object
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 |
# File 'lib/collins/cli/find.rb', line 145 def run! raise "Options not yet parsed with #parse!" unless @parsed raise "Options not yet validated with #validate!" unless @validated if [:mode] == :help puts parser else page = 0 assets, res = [], [] begin loop do break if ![:limit].nil? and assets.length >= [:limit] res = collins.find(query_opts.merge({:page => page})) break if res.empty? assets = assets.concat res page += 1 end rescue => e raise "Error querying collins: #{e.}" end unless [:limit].nil? format_assets(assets.first([:limit]), ) else format_assets(assets, ) end end true end |
#validate! ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/collins/cli/find.rb', line 122 def validate! raise "Options not yet parsed with #parse!" unless @parsed # fix bug where assets wont get found if they dont have that meta attribute search_attrs.delete(:hostname) if search_attrs[:hostname].nil? # for any search attributes, lets not pass arrays of 1 element # as that will confuse as_query? search_attrs.each do |k,v| if v.is_a? Array search_attrs[k] = v.first if v.length == 1 search_attrs[k] = nil if v.empty? end end # merge search_attrs into query if as_query?(search_attrs) query_opts[:query] = convert_to_query(query_opts[:operation], search_attrs, ) else query_opts.merge!(search_attrs) end @validated = true self end |