X-Git-Url: https://review.fuel-infra.org/gitweb?a=blobdiff_plain;ds=sidebyside;f=doc%2Fclasses%2FMCollective%2FRPC%2FHelpers.html;fp=doc%2Fclasses%2FMCollective%2FRPC%2FHelpers.html;h=5e06bcefe02d7e85296927761f1b00284f48f59b;hb=d1f1649ba43c5cbc43c4beb2380096ba051d646a;hp=0000000000000000000000000000000000000000;hpb=8a3fe7daeecccf43dd71c59371c5005400d35101;p=packages%2Fprecise%2Fmcollective.git diff --git a/doc/classes/MCollective/RPC/Helpers.html b/doc/classes/MCollective/RPC/Helpers.html new file mode 100644 index 0000000..5e06bce --- /dev/null +++ b/doc/classes/MCollective/RPC/Helpers.html @@ -0,0 +1,595 @@ + + + + + + Class: MCollective::RPC::Helpers + + + + + + + + + + +
+ + + + + + + + + + + + + + +
ClassMCollective::RPC::Helpers
In: + + lib/mcollective/rpc/helpers.rb + +
+
Parent: + Object +
+
+ + +
+ + + +
+ +
+

+Various utilities for the RPC system +

+ +
+ + +
+ +
+

Methods

+ + +
+ +
+ + + + +
+ + + + + + + + + +
+

Public Class methods

+ +
+ + + + +
+

+Add SimpleRPC common options +

+

[Source]

+
+
+     # File lib/mcollective/rpc/helpers.rb, line 254
+254:       def self.add_simplerpc_options(parser, options)
+255:         parser.separator ""
+256:         parser.separator "RPC Options"
+257: 
+258:         # add SimpleRPC specific options to all clients that use our library
+259:         parser.on('--np', '--no-progress', 'Do not show the progress bar') do |v|
+260:           options[:progress_bar] = false
+261:         end
+262: 
+263:         parser.on('--one', '-1', 'Send request to only one discovered nodes') do |v|
+264:           options[:mcollective_limit_targets] = 1
+265:         end
+266: 
+267:         parser.on('--batch SIZE', Integer, 'Do requests in batches') do |v|
+268:           options[:batch_size] = v
+269:         end
+270: 
+271:         parser.on('--batch-sleep SECONDS', Float, 'Sleep time between batches') do |v|
+272:           options[:batch_sleep_time] = v
+273:         end
+274: 
+275:         parser.on('--limit-seed NUMBER', Integer, 'Seed value for deterministic random batching') do |v|
+276:           options[:limit_seed] = v
+277:         end
+278: 
+279:         parser.on('--limit-nodes COUNT', '--ln', '--limit', 'Send request to only a subset of nodes, can be a percentage') do |v|
+280:           raise "Invalid limit specified: #{v} valid limits are /^\d+%*$/" unless v =~ /^\d+%*$/
+281: 
+282:           if v =~ /^\d+$/
+283:             options[:mcollective_limit_targets] = v.to_i
+284:           else
+285:             options[:mcollective_limit_targets] = v
+286:           end
+287:         end
+288: 
+289:         parser.on('--json', '-j', 'Produce JSON output') do |v|
+290:           options[:progress_bar] = false
+291:           options[:output_format] = :json
+292:         end
+293: 
+294:         parser.on('--display MODE', 'Influence how results are displayed. One of ok, all or failed') do |v|
+295:           if v == "all"
+296:             options[:force_display_mode] = :always
+297:           else
+298:             options[:force_display_mode] = v.intern
+299:           end
+300: 
+301:           raise "--display has to be one of 'ok', 'all' or 'failed'" unless [:ok, :failed, :always].include?(options[:force_display_mode])
+302:         end
+303:       end
+
+
+
+
+ +
+ + + + +
+

+Given an array of something, make sure each is a string chomp off any new +lines and return just the array of hosts +

+

[Source]

+
+
+    # File lib/mcollective/rpc/helpers.rb, line 29
+29:       def self.extract_hosts_from_array(hosts)
+30:         [hosts].flatten.map do |host|
+31:           raise "#{host} should be a string" unless host.is_a?(String)
+32:           host.chomp
+33:         end
+34:       end
+
+
+
+
+ +
+ + + + +
+

+Parse JSON output as produced by printrpc and extract the +"sender" of each rpc response +

+

+The simplist valid JSON based data would be: +

+

+[ +

+
+ {"sender" => "example.com"},
+ {"sender" => "another.com"}
+
+

+] +

+

[Source]

+
+
+    # File lib/mcollective/rpc/helpers.rb, line 14
+14:       def self.extract_hosts_from_json(json)
+15:         hosts = JSON.parse(json)
+16: 
+17:         raise "JSON hosts list is not an array" unless hosts.is_a?(Array)
+18: 
+19:         hosts.map do |host|
+20:           raise "JSON host list is not an array of Hashes" unless host.is_a?(Hash)
+21:           raise "JSON host list does not have senders in it" unless host.include?("sender")
+22: 
+23:           host["sender"]
+24:         end.uniq
+25:       end
+
+
+
+
+ +
+ + + + +
+

+Backward compatible display block for results without a DDL +

+

[Source]

+
+
+     # File lib/mcollective/rpc/helpers.rb, line 202
+202:       def self.old_rpcresults(result, flags = {})
+203:         result_text = ""
+204: 
+205:         if flags[:flatten]
+206:           result.each do |r|
+207:             if r[:statuscode] <= 1
+208:               data = r[:data]
+209: 
+210:               unless data.is_a?(String)
+211:                 result_text << data.pretty_inspect
+212:               else
+213:                 result_text << data
+214:               end
+215:             else
+216:               result_text << r.pretty_inspect
+217:             end
+218:           end
+219: 
+220:           result_text << ""
+221:         else
+222:           [result].flatten.each do |r|
+223: 
+224:             if flags[:verbose]
+225:               result_text << "%-40s: %s\n" % [r[:sender], r[:statusmsg]]
+226: 
+227:               if r[:statuscode] <= 1
+228:                 r[:data].pretty_inspect.split("\n").each {|m| result_text += "    #{m}"}
+229:                 result_text << "\n\n"
+230:               elsif r[:statuscode] == 2
+231:                 # dont print anything, no useful data to display
+232:                 # past what was already shown
+233:               elsif r[:statuscode] == 3
+234:                 # dont print anything, no useful data to display
+235:                 # past what was already shown
+236:               elsif r[:statuscode] == 4
+237:                 # dont print anything, no useful data to display
+238:                 # past what was already shown
+239:               else
+240:                 result_text << "    #{r[:statusmsg]}"
+241:               end
+242:             else
+243:               unless r[:statuscode] == 0
+244:                 result_text << "%-40s %s\n" % [r[:sender], Util.colorize(:red, r[:statusmsg])]
+245:               end
+246:             end
+247:           end
+248:         end
+249: 
+250:         result_text << ""
+251:       end
+
+
+
+
+ +
+ + + + +
+

+Returns a blob of text representing the results in a standard way +

+

+It tries hard to do sane things so you often should not need to write your +own display functions +

+

+If the agent you are getting results for has a DDL it will use the hints in there to do the right +thing specifically it will look at the values of display in the DDL to choose when to show results +

+

+If you do not have a DDL you can pass these +flags: +

+
+   printrpc exim.mailq, :flatten => true
+   printrpc exim.mailq, :verbose => true
+
+

+If you‘ve asked it to flatten the result it will not print sender +hostnames, it will just print the result as if it‘s one huge result, +handy for things like showing a combined mailq. +

+

[Source]

+
+
+     # File lib/mcollective/rpc/helpers.rb, line 54
+ 54:       def self.rpcresults(result, flags = {})
+ 55:         flags = {:verbose => false, :flatten => false, :format => :console, :force_display_mode => false}.merge(flags)
+ 56: 
+ 57:         result_text = ""
+ 58:         ddl = nil
+ 59: 
+ 60:         # if running in verbose mode, just use the old style print
+ 61:         # no need for all the DDL helpers obfuscating the result
+ 62:         if flags[:format] == :json
+ 63:           if STDOUT.tty?
+ 64:             result_text = JSON.pretty_generate(result)
+ 65:           else
+ 66:             result_text = result.to_json
+ 67:           end
+ 68:         else
+ 69:           if flags[:verbose]
+ 70:             result_text = old_rpcresults(result, flags)
+ 71:           else
+ 72:             [result].flatten.each do |r|
+ 73:               begin
+ 74:                 ddl ||= DDL.new(r.agent).action_interface(r.action.to_s)
+ 75: 
+ 76:                 sender = r[:sender]
+ 77:                 status = r[:statuscode]
+ 78:                 message = r[:statusmsg]
+ 79:                 result = r[:data]
+ 80: 
+ 81:                 if flags[:force_display_mode]
+ 82:                   display = flags[:force_display_mode]
+ 83:                 else
+ 84:                   display = ddl[:display]
+ 85:                 end
+ 86: 
+ 87:                 # appand the results only according to what the DDL says
+ 88:                 case display
+ 89:                   when :ok
+ 90:                     if status == 0
+ 91:                       result_text << text_for_result(sender, status, message, result, ddl)
+ 92:                     end
+ 93: 
+ 94:                   when :failed
+ 95:                     if status > 0
+ 96:                       result_text << text_for_result(sender, status, message, result, ddl)
+ 97:                     end
+ 98: 
+ 99:                   when :always
+100:                     result_text << text_for_result(sender, status, message, result, ddl)
+101: 
+102:                   when :flatten
+103:                     result_text << text_for_flattened_result(status, result)
+104: 
+105:                 end
+106:               rescue Exception => e
+107:                 # no DDL so just do the old style print unchanged for
+108:                 # backward compat
+109:                 result_text = old_rpcresults(result, flags)
+110:               end
+111:             end
+112:           end
+113:         end
+114: 
+115:         result_text
+116:       end
+
+
+
+
+ +
+ + + + +
+

+Returns text representing a flattened result of only good data +

+

[Source]

+
+
+     # File lib/mcollective/rpc/helpers.rb, line 189
+189:       def self.text_for_flattened_result(status, result)
+190:         result_text = ""
+191: 
+192:         if status <= 1
+193:           unless result.is_a?(String)
+194:             result_text << result.pretty_inspect
+195:           else
+196:             result_text << result
+197:           end
+198:         end
+199:       end
+
+
+
+
+ +
+ + + + +
+

+Return text representing a result +

+

[Source]

+
+
+     # File lib/mcollective/rpc/helpers.rb, line 119
+119:       def self.text_for_result(sender, status, msg, result, ddl)
+120:         statusses = ["",
+121:                      Util.colorize(:red, "Request Aborted"),
+122:                      Util.colorize(:yellow, "Unknown Action"),
+123:                      Util.colorize(:yellow, "Missing Request Data"),
+124:                      Util.colorize(:yellow, "Invalid Request Data"),
+125:                      Util.colorize(:red, "Unknown Request Status")]
+126: 
+127:         result_text = "%-40s %s\n" % [sender, statusses[status]]
+128:         result_text << "   %s\n" % [Util.colorize(:yellow, msg)] unless msg == "OK"
+129: 
+130:         # only print good data, ignore data that results from failure
+131:         if status == 0
+132:           if result.is_a?(Hash)
+133:             # figure out the lengths of the display as strings, we'll use
+134:             # it later to correctly justify the output
+135:             lengths = result.keys.map do |k|
+136:               begin
+137:                 ddl[:output][k][:display_as].size
+138:               rescue
+139:                 k.to_s.size
+140:               end
+141:             end
+142: 
+143:             result.keys.sort_by{|k| k}.each do |k|
+144:               # get all the output fields nicely lined up with a
+145:               # 3 space front padding
+146:               begin
+147:                 display_as = ddl[:output][k][:display_as]
+148:               rescue
+149:                 display_as = k.to_s
+150:               end
+151: 
+152:               display_length = display_as.size
+153:               padding = lengths.max - display_length + 3
+154:               result_text << " " * padding
+155: 
+156:               result_text << "#{display_as}:"
+157: 
+158:               if [String, Numeric].include?(result[k].class)
+159:                 lines = result[k].to_s.split("\n")
+160: 
+161:                 if lines.empty?
+162:                   result_text << "\n"
+163:                 else
+164:                   lines.each_with_index do |line, i|
+165:                     i == 0 ? padtxt = " " : padtxt = " " * (padding + display_length + 2)
+166: 
+167:                     result_text << "#{padtxt}#{line}\n"
+168:                   end
+169:                 end
+170:               else
+171:                 padding = " " * (lengths.max + 5)
+172:                 result_text << " " << result[k].pretty_inspect.split("\n").join("\n" << padding) << "\n"
+173:               end
+174:             end
+175:           elsif status == 1
+176:             # for status 1 we dont want to show half baked
+177:             # data by default since the DDL will supply all the defaults
+178:             # it just doesnt look right
+179:           else
+180:             result_text << "\n\t" + result.pretty_inspect.split("\n").join("\n\t")
+181:           end
+182:         end
+183: 
+184:         result_text << "\n"
+185:         result_text
+186:       end
+
+
+
+
+ + +
+ + +
+ + +
+

[Validate]

+
+ + + \ No newline at end of file