X-Git-Url: https://review.fuel-infra.org/gitweb?a=blobdiff_plain;ds=sidebyside;f=doc%2Fclasses%2FMCollective%2FRPC%2FAgent.html;fp=doc%2Fclasses%2FMCollective%2FRPC%2FAgent.html;h=4050b22bd367f72ae6755b44c1a5c716fa2e5794;hb=d1f1649ba43c5cbc43c4beb2380096ba051d646a;hp=0000000000000000000000000000000000000000;hpb=8a3fe7daeecccf43dd71c59371c5005400d35101;p=packages%2Fprecise%2Fmcollective.git diff --git a/doc/classes/MCollective/RPC/Agent.html b/doc/classes/MCollective/RPC/Agent.html new file mode 100644 index 0000000..4050b22 --- /dev/null +++ b/doc/classes/MCollective/RPC/Agent.html @@ -0,0 +1,462 @@ + + + + +
+Class | +MCollective::RPC::Agent | +
In: | +
+
+ lib/mcollective/rpc/agent.rb
+
+ + |
+
Parent: | ++ Object + | +
+A wrapper around the traditional agent, it takes care of a lot of the +tedious setup you would do for each agent allowing you to just create +methods following a naming standard leaving the heavy lifting up to this +clas. +
++See marionette-collective.org/simplerpc/agents.html +
++It only really makes sense to use this with a Simple RPC client on the other end, basic usage would be: +
++ module MCollective + module Agent + class Helloworld<RPC::Agent + action "hello" do + reply[:msg] = "Hello #{request[:name]}" + end + + action "foo" do + implemented_by "/some/script.sh" + end + end + end + end ++
+If you wish to implement the logic for an action using an external script +use the implemented_by method that will cause your script to be run with 2 +arguments. +
++The first argument is a file containing JSON with the request and the 2nd +argument is where the script should save its output as a JSON hash. +
++We also currently have the validation code in here, this will be moved to +plugins soon. +
+ +agent_name | +[RW] | ++ |
config | +[R] | ++ |
ddl | +[R] | ++ |
logger | +[R] | ++ |
meta | +[R] | ++ |
reply | +[RW] | ++ |
request | +[RW] | ++ |
timeout | +[R] | ++ |
+By default RPC Agents support a toggle in the configuration that +can enable and disable them based on the agent name +
++Example an agent called Foo can have: +
++plugin.foo.activate_agent = false +
++and this will prevent the agent from loading on this particular machine. +
++Agents can use the activate_when helper to +override this for example: +
++activate_when do +
++ File.exist?("/usr/bin/puppet") ++
+end +
+ ++ # File lib/mcollective/rpc/agent.rb, line 142 +142: def self.activate? +143: agent_name = self.to_s.split("::").last.downcase +144: +145: log_code(:PLMC37, "Starting default activation checks for the '%{agent}' agent", :debug, :agent => agent_name) +146: +147: should_activate = Util.str_to_bool(Config.instance.pluginconf.fetch("#{agent_name}.activate_agent", true)) +148: +149: unless should_activate +150: log_code(:PLMC38, "Found plugin configuration '%{agent}.activate_agent' with value '%{should_activate}'", :debug, :agent => agent_name, :should_activate => should_activate) +151: end +152: +153: return should_activate +154: end ++
+ # File lib/mcollective/rpc/agent.rb, line 40 +40: def initialize +41: @agent_name = self.class.to_s.split("::").last.downcase +42: +43: load_ddl +44: +45: @logger = Log.instance +46: @config = Config.instance +47: +48: # if we have a global authorization provider enable it +49: # plugins can still override it per plugin +50: self.class.authorized_by(@config.rpcauthprovider) if @config.rpcauthorization +51: +52: startup_hook +53: end ++
+ # File lib/mcollective/rpc/agent.rb, line 64 + 64: def handlemsg(msg, connection) + 65: @request = RPC::Request.new(msg, @ddl) + 66: @reply = RPC::Reply.new(@request.action, @ddl) + 67: + 68: begin + 69: # Incoming requests need to be validated against the DDL thus reusing + 70: # all the work users put into creating DDLs and creating a consistent + 71: # quality of input validation everywhere with the a simple once off + 72: # investment of writing a DDL + 73: @request.validate! + 74: + 75: # Calls the authorization plugin if any is defined + 76: # if this raises an exception we wil just skip processing this + 77: # message + 78: authorization_hook(@request) if respond_to?("authorization_hook") + 79: + 80: # Audits the request, currently continues processing the message + 81: # we should make this a configurable so that an audit failure means + 82: # a message wont be processed by this node depending on config + 83: audit_request(@request, connection) + 84: + 85: before_processing_hook(msg, connection) + 86: + 87: if respond_to?("#{@request.action}_action") + 88: send("#{@request.action}_action") + 89: else + 90: log_code(:PLMC36, "Unknown action '%{action}' for agent '%{agent}'", :warn, :action => @request.action, :agent => @request.agent) + 91: raise UnknownRPCAction, "Unknown action '#{@request.action}' for agent '#{@request.agent}'" + 92: end + 93: rescue RPCAborted => e + 94: @reply.fail e.to_s, 1 + 95: + 96: rescue UnknownRPCAction => e + 97: @reply.fail e.to_s, 2 + 98: + 99: rescue MissingRPCData => e +100: @reply.fail e.to_s, 3 +101: +102: rescue InvalidRPCData, DDLValidationError => e +103: @reply.fail e.to_s, 4 +104: +105: rescue UnknownRPCError => e +106: Log.error("%s#%s failed: %s: %s" % [@agent_name, @request.action, e.class, e.to_s]) +107: Log.error(e.backtrace.join("\n\t")) +108: @reply.fail e.to_s, 5 +109: +110: rescue Exception => e +111: Log.error("%s#%s failed: %s: %s" % [@agent_name, @request.action, e.class, e.to_s]) +112: Log.error(e.backtrace.join("\n\t")) +113: @reply.fail e.to_s, 5 +114: +115: end +116: +117: after_processing_hook +118: +119: if @request.should_respond? +120: return @reply.to_hash +121: else +122: log_code(:PLMC35, "Client did not request a response, surpressing reply", :debug) +123: return nil +124: end +125: end ++
+ # File lib/mcollective/rpc/agent.rb, line 55 +55: def load_ddl +56: @ddl = DDL.new(@agent_name, :agent) +57: @meta = @ddl.meta +58: @timeout = @meta[:timeout] || 10 +59: +60: rescue Exception => e +61: DDL.validation_fail!(:PLMC24, "Failed to load DDL for the '%{agent}' agent, DDLs are required: %{error_class}: %{error}", :error, :agent => @agent_name, :error_class => e.class, :error => e.to_s) +62: end ++