class MCollective::RPC::Agent

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.

Attributes

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

Public Class Methods

actions() click to toggle source

Returns an array of actions this agent support

# File lib/mcollective/rpc/agent.rb, line 143
def self.actions
    public_instance_methods.sort.grep(%r_action$/).map do |method|
        $1 if method =~ %r(.+)_action$/
    end
end
help(template) click to toggle source

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

# File lib/mcollective/rpc/agent.rb, line 129
def self.help(template)
    if @ddl
        @ddl.help(template)
    else
        "No DDL defined"
    end
end
new() click to toggle source
# File lib/mcollective/rpc/agent.rb, line 44
def initialize
    # Default meta data unset
    @meta = {:timeout     => 10,
             :name        => "Unknown",
             :description => "Unknown",
             :author      => "Unknown",
             :license     => "Unknown",
             :version     => "Unknown",
             :url         => "Unknown"}

    @timeout = meta[:timeout] || 10
    @logger = Log.instance
    @config = Config.instance
    @agent_name = self.class.to_s.split("::").last.downcase

    # Loads the DDL so we can later use it for validation
    # and help generation
    begin
        @ddl = DDL.new(@agent_name)
    rescue
        @ddl = nil
    end

    # if we have a global authorization provider enable it
    # plugins can still override it per plugin
    self.class.authorized_by(@config.rpcauthprovider) if @config.rpcauthorization

    startup_hook
end

Public Instance Methods

handlemsg(msg, connection) click to toggle source
# File lib/mcollective/rpc/agent.rb, line 74
def handlemsg(msg, connection)
    @request = RPC.request(msg)
    @reply = RPC.reply

    begin
        # Calls the authorization plugin if any is defined
        # if this raises an exception we wil just skip processing this
        # message
        authorization_hook(@request) if respond_to?("authorization_hook")


        # Audits the request, currently continues processing the message
        # we should make this a configurable so that an audit failure means
        # a message wont be processed by this node depending on config
        audit_request(@request, connection)

        before_processing_hook(msg, connection)

        if respond_to?("#{@request.action}_action")
            send("#{@request.action}_action")
        else
            raise UnknownRPCAction, "Unknown action: #{@request.action}"
        end
    rescue RPCAborted => e
        @reply.fail e.to_s, 1

    rescue UnknownRPCAction => e
        @reply.fail e.to_s, 2

    rescue MissingRPCData => e
        @reply.fail e.to_s, 3

    rescue InvalidRPCData => e
        @reply.fail e.to_s, 4

    rescue UnknownRPCError => e
        @reply.fail e.to_s, 5

    rescue Exception => e
        @reply.fail e.to_s, 5

    end

    after_processing_hook

    if @request.should_respond?
        return @reply.to_hash
    else
        Log.debug("Client did not request a response, surpressing reply")
        return nil
    end
end
help() click to toggle source

to auto generate help

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