| 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
matadata :name => "Test SimpleRPC Agent",
:description => "A simple test",
:author => "You",
:license => "1.1",
:url => "http://your.com/,
:timeout => 60
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.
| config | [R] | |
| ddl | [R] | |
| logger | [R] | |
| meta | [RW] | |
| 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 143
143: def self.activate?
144: agent_name = self.to_s.split("::").last.downcase
145:
146: Log.debug("Starting default activation checks for #{agent_name}")
147:
148: should_activate = Config.instance.pluginconf["#{agent_name}.activate_agent"]
149:
150: if should_activate
151: Log.debug("Found plugin config #{agent_name}.activate_agent with value #{should_activate}")
152: unless should_activate =~ /^1|y|true$/
153: return false
154: end
155: end
156:
157: return true
158: end
# File lib/mcollective/rpc/agent.rb, line 44
44: def initialize
45: # Default meta data unset
46: @meta = {:timeout => 10,
47: :name => "Unknown",
48: :description => "Unknown",
49: :author => "Unknown",
50: :license => "Unknown",
51: :version => "Unknown",
52: :url => "Unknown"}
53:
54: @timeout = meta[:timeout] || 10
55: @logger = Log.instance
56: @config = Config.instance
57: @agent_name = self.class.to_s.split("::").last.downcase
58:
59: # Loads the DDL so we can later use it for validation
60: # and help generation
61: begin
62: @ddl = DDL.new(@agent_name)
63: rescue Exception => e
64: Log.debug("Failed to load DDL for agent: #{e.class}: #{e}")
65: @ddl = nil
66: end
67:
68: # if we have a global authorization provider enable it
69: # plugins can still override it per plugin
70: self.class.authorized_by(@config.rpcauthprovider) if @config.rpcauthorization
71:
72: startup_hook
73: end
# File lib/mcollective/rpc/agent.rb, line 75
75: def handlemsg(msg, connection)
76: @request = RPC.request(msg)
77: @reply = RPC.reply
78:
79: begin
80: # Calls the authorization plugin if any is defined
81: # if this raises an exception we wil just skip processing this
82: # message
83: authorization_hook(@request) if respond_to?("authorization_hook")
84:
85:
86: # Audits the request, currently continues processing the message
87: # we should make this a configurable so that an audit failure means
88: # a message wont be processed by this node depending on config
89: audit_request(@request, connection)
90:
91: before_processing_hook(msg, connection)
92:
93: if respond_to?("#{@request.action}_action")
94: send("#{@request.action}_action")
95: else
96: raise UnknownRPCAction, "Unknown action: #{@request.action}"
97: end
98: rescue RPCAborted => e
99: @reply.fail e.to_s, 1
100:
101: rescue UnknownRPCAction => e
102: @reply.fail e.to_s, 2
103:
104: rescue MissingRPCData => e
105: @reply.fail e.to_s, 3
106:
107: rescue InvalidRPCData => e
108: @reply.fail e.to_s, 4
109:
110: rescue UnknownRPCError => e
111: @reply.fail e.to_s, 5
112:
113: rescue Exception => e
114: @reply.fail e.to_s, 5
115:
116: end
117:
118: after_processing_hook
119:
120: if @request.should_respond?
121: return @reply.to_hash
122: else
123: Log.debug("Client did not request a response, surpressing reply")
124: return nil
125: end
126: end