| 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 130
130: def self.activate?
131: agent_name = self.to_s.split("::").last.downcase
132:
133: Log.debug("Starting default activation checks for #{agent_name}")
134:
135: should_activate = Config.instance.pluginconf["#{agent_name}.activate_agent"]
136:
137: if should_activate
138: Log.debug("Found plugin config #{agent_name}.activate_agent with value #{should_activate}")
139: unless should_activate =~ /^1|y|true$/
140: return false
141: end
142: end
143:
144: return true
145: end
# File lib/mcollective/rpc/agent.rb, line 37
37: def initialize
38: @agent_name = self.class.to_s.split("::").last.downcase
39:
40: load_ddl
41:
42: @logger = Log.instance
43: @config = Config.instance
44:
45: # if we have a global authorization provider enable it
46: # plugins can still override it per plugin
47: self.class.authorized_by(@config.rpcauthprovider) if @config.rpcauthorization
48:
49: startup_hook
50: end
# File lib/mcollective/rpc/agent.rb, line 62
62: def handlemsg(msg, connection)
63: @request = RPC::Request.new(msg)
64: @reply = RPC::Reply.new(@request.action, @ddl)
65:
66: begin
67: # Calls the authorization plugin if any is defined
68: # if this raises an exception we wil just skip processing this
69: # message
70: authorization_hook(@request) if respond_to?("authorization_hook")
71:
72:
73: # Audits the request, currently continues processing the message
74: # we should make this a configurable so that an audit failure means
75: # a message wont be processed by this node depending on config
76: audit_request(@request, connection)
77:
78: before_processing_hook(msg, connection)
79:
80: if respond_to?("#{@request.action}_action")
81: send("#{@request.action}_action")
82: else
83: raise UnknownRPCAction, "Unknown action: #{@request.action}"
84: end
85: rescue RPCAborted => e
86: @reply.fail e.to_s, 1
87:
88: rescue UnknownRPCAction => e
89: @reply.fail e.to_s, 2
90:
91: rescue MissingRPCData => e
92: @reply.fail e.to_s, 3
93:
94: rescue InvalidRPCData => e
95: @reply.fail e.to_s, 4
96:
97: rescue UnknownRPCError => e
98: @reply.fail e.to_s, 5
99:
100: rescue Exception => e
101: @reply.fail e.to_s, 5
102:
103: end
104:
105: after_processing_hook
106:
107: if @request.should_respond?
108: return @reply.to_hash
109: else
110: Log.debug("Client did not request a response, surpressing reply")
111: return nil
112: end
113: end
# File lib/mcollective/rpc/agent.rb, line 52
52: def load_ddl
53: @ddl = DDL.new(@agent_name, :agent)
54: @meta = @ddl.meta
55: @timeout = @meta[:timeout] || 10
56:
57: rescue Exception => e
58: Log.error("Failed to load DDL for the '%s' agent, DDLs are required: %s: %s" % [@agent_name, e.class, e.to_s])
59: raise DDLValidationError
60: end