X-Git-Url: https://review.fuel-infra.org/gitweb?a=blobdiff_plain;ds=sidebyside;f=lib%2Fmcollective%2Frpc.rb;fp=lib%2Fmcollective%2Frpc.rb;h=575d069b1f1bd7087e5e46bb52b210c8bdaeb41c;hb=b87d2f4e68281062df1913440ca5753ae63314a9;hp=0000000000000000000000000000000000000000;hpb=ab0ea530b8ac956091f17b104ab2311336cfc250;p=packages%2Fprecise%2Fmcollective.git diff --git a/lib/mcollective/rpc.rb b/lib/mcollective/rpc.rb new file mode 100644 index 0000000..575d069 --- /dev/null +++ b/lib/mcollective/rpc.rb @@ -0,0 +1,182 @@ +require 'pp' + +module MCollective + # Toolset to create a standard interface of client and agent using + # an RPC metaphor, standard compliant agents will make it easier + # to create generic clients like web interfaces etc + module RPC + autoload :ActionRunner, "mcollective/rpc/actionrunner" + autoload :Agent, "mcollective/rpc/agent" + autoload :Audit, "mcollective/rpc/audit" + autoload :Client, "mcollective/rpc/client" + autoload :Helpers, "mcollective/rpc/helpers" + autoload :Progress, "mcollective/rpc/progress" + autoload :Reply, "mcollective/rpc/reply" + autoload :Request, "mcollective/rpc/request" + autoload :Result, "mcollective/rpc/result" + autoload :Stats, "mcollective/rpc/stats" + + # Creates a standard options hash, pass in a block to add extra headings etc + # see Optionparser + def rpcoptions + oparser = MCollective::Optionparser.new({:verbose => false, :progress_bar => true}, "filter") + + options = oparser.parse do |parser, options| + if block_given? + yield(parser, options) + end + + Helpers.add_simplerpc_options(parser, options) + end + + return options + end + + # Wrapper to create clients, supposed to be used as + # a mixin: + # + # include MCollective::RPC + # + # exim = rpcclient("exim") + # printrpc exim.mailq + # + # or + # + # rpcclient("exim") do |exim| + # printrpc exim.mailq + # end + # + # It will take a few flags: + # :configfile => "etc/client.cfg" + # :options => options + # :exit_on_failure => true + # + # Options would be a build up options hash from the Optionparser + # you can use the rpcoptions helper to create this + # + # :exit_on_failure is true by default, and causes the application to + # exit if there is a failure constructing the RPC client. Set this flag + # to false to cause an Exception to be raised instead. + def rpcclient(agent, flags = {}) + configfile = flags[:configfile] || "/etc/mcollective/client.cfg" + options = flags[:options] || nil + + if flags.key?(:exit_on_failure) + exit_on_failure = flags[:exit_on_failure] + else + # We exit on failure by default for CLI-friendliness + exit_on_failure = true + end + + begin + if options + rpc = Client.new(agent, :configfile => options[:config], :options => options) + @options = rpc.options + else + rpc = Client.new(agent, :configfile => configfile) + @options = rpc.options + end + rescue Exception => e + if exit_on_failure + puts("Could not create RPC client: #{e}") + exit! + else + raise e + end + end + + if block_given? + yield(rpc) + else + return rpc + end + end + + # means for other classes to drop stats into this module + # its a bit hacky but needed so that the mixin methods like + # printrpcstats can easily get access to it without + # users having to pass it around in params. + def self.stats(stats) + @@stats = stats + end + + # means for other classes to drop discovered hosts into this module + # its a bit hacky but needed so that the mixin methods like + # printrpcstats can easily get access to it without + # users having to pass it around in params. + def self.discovered(discovered) + @@discovered = discovered + end + + # Prints stats, requires stats to be saved from elsewhere + # using the MCollective::RPC.stats method. + # + # If you've passed -v on the command line a detailed stat block + # will be printed, else just a one liner. + # + # You can pass flags into it: + # + # printrpcstats :caption => "Foo", :summarize => true + # + # This will use "Foo" as the caption to the stats in verbose + # mode and print out any aggregate summary information if present + def printrpcstats(flags={}) + return unless @options[:output_format] == :console + + flags = {:summarize => false, :caption => "rpc stats"}.merge(flags) + + verbose = @options[:verbose] rescue verbose = false + + begin + stats = @@stats + rescue + puts("no stats to display") + return + end + + puts stats.report(flags[:caption], flags[:summarize], verbose) + end + + # Prints the result of an RPC call. + # + # In the default quiet mode - no flattening or verbose - only results + # that produce an error will be printed + # + # To get details of each result run with the -v command line option. + def printrpc(result, flags = {}) + verbose = @options[:verbose] rescue verbose = false + verbose = flags[:verbose] || verbose + flatten = flags[:flatten] || false + format = @options[:output_format] + forced_mode = @options[:force_display_mode] || false + + result_text = Helpers.rpcresults(result, {:verbose => verbose, :flatten => flatten, :format => format, :force_display_mode => forced_mode}) + + if result.is_a?(Array) && format == :console + puts "\n%s\n" % [ result_text ] + else + # when we get just one result to print dont pad them all with + # blank spaces etc, just print the individual result with no + # padding + puts result_text unless result_text == "" + end + end + + # Wrapper for MCollective::Util.empty_filter? to make clients less fugly + # to write - ticket #18 + def empty_filter?(options) + if options.include?(:filter) + Util.empty_filter?(options[:filter]) + else + Util.empty_filter?(options) + end + end + + def self.const_missing(const_name) + super unless const_name == :DDL + + Log.warn("MCollective::RPC::DDL is deprecatd, please use MCollective::DDL instead") + MCollective::DDL + end + end +end