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.

Methods

actions   activate?   handlemsg   help   help   new  

Attributes

config  [R] 
ddl  [R] 
logger  [R] 
meta  [RW] 
reply  [RW] 
request  [RW] 
timeout  [R] 

Public Class methods

Returns an array of actions this agent support

[Source]

     # File lib/mcollective/rpc/agent.rb, line 176
176:       def self.actions
177:         public_instance_methods.sort.grep(/_action$/).map do |method|
178:           $1 if method =~ /(.+)_action$/
179:         end
180:       end

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

[Source]

     # 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

Generates help using the template based on the data created with metadata and input

[Source]

     # File lib/mcollective/rpc/agent.rb, line 162
162:       def self.help(template)
163:         if @ddl
164:           @ddl.help(template)
165:         else
166:           "No DDL defined"
167:         end
168:       end

[Source]

    # 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

Public Instance methods

[Source]

     # 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

to auto generate help

[Source]

     # File lib/mcollective/rpc/agent.rb, line 171
171:       def help
172:         self.help("#{@config[:configdir]}/rpc-help.erb")
173:       end

[Validate]