Registration is a process where an agent on the server sends out a message on to the collective.registration.agent
Topic every registerinterval
period. The default registration agent AgentList
sends out a list of the mcollective agents installed and running in mcollectived
.
In a default installation every server publishes these registration messages, but nothing subscribes to them. I believe the original use was intended to simply keep the TCP connection alive in the presence of connection-tracking firewalls. Now that this is handled by the heartbeat
support in STOMP 1.1 protocol, registration … well, it has found its own reason to live.
Many people have started doing useful things with the registration agent. Let’s show you how to build your own agent, and your own collector to grab that data and do something with it.
If you were to look at the default registration agent in your libdir directory you’d be amazed at how simple it is.
$
cat /
usr/libexec/mcollective
/mcollective/registration/agentlist.rbmodule
MCollective
module
Registration
# A registration plugin that simply sends in the list of agents we have
class
Agentlist
<
Base
def
body
Agents
.
agentlist
end
end
end
end
Yeah, it is simple. The module should subclass MCollective::Registration::Base
. Define a body
method which returns anything you want, and that data is sent out to the collective.registration.agent
topic for you. You can make the data as complex or as simple as meets your needs. Remember that by default, nothing reads what this agent publishes.
If you send the value nil
then no message will be sent out.
R.I. Pienaar wrote a registration plugin that supplies not just the installed agents, but also the identity, facts, collectives, and Puppet classes. You can find that at https://github.com/puppetlabs/mcollective-plugins/blob/master/registration/meta.rb.
At one site where we wanted to reduce the registration traffic, we added a registration agent that only sent the hostname.
$
cat /
usr/libexec/mcollective
/mcollective/registration/hostname.rbmodule
MCollective
module
Registration
# A registration plugin that simply sends the hostname
class
Hostname
<
Base
require
'socket'
def
body
Socket
.
gethostname
end
end
end
end
Then we changed the server configuration to only send the registration data every hour:
/etc/mcollective/server.cfg.
registerinterval = 3600 registration = Hostname registration_collective = mcollective
Notice the registration_collective
parameter there. We haven’t talked about this before now. If you have localized traffic as we have suggested in Localizing Traffic, you may want to put registration traffic on either its own collective, or on a global collective distinct from what your primary collective is set to. It depends on what your needs are, and where your listeners are expecting to receive this information.
Collecting responses is nothing more than listening to registration information published on the collectivename.registration.agent
Topic. Better yet, you don’t have to know how to write a topic subscriber in Ruby. Simply create an MCollective Agent named Registration (and stored in agent/registration.rb
with a method named handlemsg
. Here is a simple registration agent that simply logs the sender, and the time that the sender sent the message.
$
cat /
module MCollective module Agent class Registration attr_reader :timeout, :meta require 'time' def initialize @timeout = 1 @config = Config.instance @meta = {:license => "GPLv2", :author => "Jo Rhett <[email protected]>", :url => "http://shop.oreilly.com/product/0636920032472.do"} end def handlemsg(message, connection) remotetime = Time.at( message[:msgtime] ) Log.info("server " + message[:senderid] + " sent registration with timestamp " + remotetime.to_s) return nil end def help <<-END LogOnly Registration Agent ========================== A simple registration agent that writes out one log line for each server that it receives a registration message from. END end end end endusr/libexec/mcollective
/mcollective/registration/registration.rb
How can you tell if your agent is running? Check the debug logs. If the agent has a syntax error you might get an Error:
E, [2014-02-26T02:37:06.633580 #18327] ERROR -- : pluginmanager.rb:171:in `loadclass' Failed to load MCollective::Agent::Registration: /usr/libexec/mcollective/mcollective/agent/registration.rb:19: syntax error, unexpected ')', expecting ']' E, [2014-02-26T02:37:06.633680 #18327] ERROR -- : agents.rb:71:in `loadagent' Loading agent registration failed: /usr/libexec/mcollective/mcollective/agent /registration.rb:19: syntax error, unexpected ')', expecting ']'
…however in most circumstances all the information is at Debug level only.
D, [2014-02-26T02:03:40.338394 #14902] DEBUG -- : agents.rb:104:in `findagentfile' Found registration at /usr/libexec/mcollective/mcollective/agent/registration.rb D, [2014-02-26T02:03:40.338512 #14902] DEBUG -- : pluginmanager.rb:167:in `loadclass' Loading MCollective::Agent::Registration from mcollective/agent/registration.rb D, [2014-02-26T02:03:40.338809 #14902] DEBUG -- : agents.rb:91:in `activate_agent?' MCollective::Agent::Registration does not have an activate? method, activating as default D, [2014-02-26T02:03:40.338915 #14902] DEBUG -- : pluginmanager.rb:44:in `<<' Registering plugin registration_agent with class MCollective::Agent::Registration single_instance: true D, [2014-02-26T02:03:40.339014 #14902] DEBUG -- : pluginmanager.rb:80:in `[]' Returning new plugin registration_agent with class MCollective::Agent::Registration D, [2014-02-26T02:03:40.339281 #14902] DEBUG -- : activemq.rb:373:in `subscribe' Subscribing to /topic/mcollective.registration.agent with headers {}
If you are using the plugin shown above, you’ll have messages like this in your logs:
I, [2014-02-26T02:39:03.832903 #18421] INFO -- : registration.rb:20:in `handlemsg' server geode sent us registration with timestamp Wed Feb 26 02:39:03 -0800 2014 I, [2014-02-26T02:39:21.333663 #18421] INFO -- : registration.rb:20:in `handlemsg' server sunstone sent us registration with timestamp Wed Feb 26 02:39:21 -0800 2014
As your registration listener needs to be named Registration, you can only have one per system. However, as registration sends to a Topic and not a Queue, you can have multiple registration listeners in your collective.
One might update a database, for example, while a different one populates a Memcache or Solr array. As there can be significant amounts of registration traffic, it is best to keep each one small and fast.
Determining how to make the file libdir/mcollective/agent/registration.rb be different on different systems is an exercise for the reader.
If you are using SSL or AES security plugins, you may have a problem collecting registration data. The registration messages will be encoded with the server’s private key. The mcollectived won’t accept the messages because they will fail validation:
W, [2014-02-26T02:17:14.203519 #15732] WARN -- : aes_security.rb:119:in `decodemsg' Could not decrypt message from client: RuntimeError: Could not find key /etc/mcollective/ssl/clients/heliotrope.example.net.pem W, [2014-02-26T02:17:14.203645 #15732] WARN -- : runner.rb:78:in `run' Failed to handle message: Could not decrypt message - MCollective::SecurityValidationFailed
What this means is that in addition to synchronizing every valid client’s public key out to each server, you will also need to synchronize every server’s public key into the same client directory on the server listening for registration data.
18.227.72.6