module MCollective module Agent # A registration agent that places information from the meta # registration class into a mongo db instance. # # To get this going you need: # # - The meta registration plugin everywhere [1] # - A mongodb instance # - The mongo gem installed ideally with the bson_ext extension # # The following configuration options exist: # - plugin.registration.mongohost where the mongodb is default: localhost # - plugin.registration.mongodb the db name default: puppet # - plugin.registration.collection the collection name default: nodes # - plugin.registration.extra_yaml_dir the presense of this key indicates a directory # containing additional yaml files to push into an 'extra' key in the registration data. All files # in the directory are pushed into a hash with keys being the file name (with the # path and .yml extension stripped) and the value being the contents. default: false # Each document will have the following data: # - fqdn - the fqdn of the sender # - lastseen - last time we got data from it # - facts - a collection of facts # - agentlist - a collection of agents on the node # - classes - a collection of classes # # A unique constraint index will be created on the fqdn of the sending # hosts. # # Released under the terms of the Apache 2 licence, contact # rip@devco.net with questions class Registration attr_reader :timeout, :meta def initialize @meta = {:license => "Apache 2", :author => "R.I.Pienaar ", :url => "https://github.com/puppetlabs/mcollective-plugins"} require 'mongo' @timeout = 2 @config = Config.instance @mongohost = @config.pluginconf["registration.mongohost"] || "localhost" @mongodb = @config.pluginconf["registration.mongodb"] || "puppet" @collection = @config.pluginconf["registration.collection"] || "nodes" @yaml_dir = @config.pluginconf["registration.extra_yaml_dir"] || false Log.instance.debug("Connecting to mongodb @ #{@mongohost} db #{@mongodb} collection #{@collection}") @dbh = Mongo::Connection.new(@mongohost).db(@mongodb) @coll = @dbh.collection(@collection) @coll.create_index("fqdn", {:unique => true, :dropDups => true}) end def handlemsg(msg, connection) req = msg[:body] if (req.kind_of?(Array)) Log.instance.warn("Got no facts - did you forget to add 'registration = Meta' to your server.cfg?"); return nill end req[:fqdn] = req[:facts]["fqdn"] req[:lastseen] = Time.now.to_i # Optionally send a list of extra yaml files if (@yaml_dir != false) req[:extra] = {} Dir[@yaml_dir + "/*.yaml"].each do | f | req[:extra][File.basename(f).split('.')[0]] = YAML.load_file(f) end end # Sometimes facter doesnt send a fqdn?! if req[:fqdn].nil? Log.instance.debug("Got stats without a FQDN in facts") return nil end by_fqdn = {:fqdn => req[:fqdn]} doc_id = nil before = Time.now.to_f begin doc = @coll.find_and_modify(:query => by_fqdn, :update => {'$set' => req}, :new => true) doc_id = doc['_id'] rescue Mongo::OperationFailure doc_id = @coll.insert(req, {:safe => true}) ensure after = Time.now.to_f Log.instance.debug("Updated data for host #{req[:fqdn]} with id #{doc_id} in #{after - before}s") end nil end def help end end end end # vi:tabstop=2:expandtab:ai:filetype=ruby