diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/defaults.rb | 4 | ||||
-rw-r--r-- | lib/puppet/feature/base.rb | 3 | ||||
-rw-r--r-- | lib/puppet/indirector/couch.rb | 68 | ||||
-rw-r--r-- | lib/puppet/indirector/facts/couch.rb | 31 | ||||
-rwxr-xr-x | lib/puppet/node/facts.rb | 5 |
5 files changed, 111 insertions, 0 deletions
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index 78f4cd52e..9de73f526 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -680,6 +680,10 @@ module Puppet and other environments normally use ``debug``."] ) + setdefaults(:couchdb, + :couchdb_url => ["http://127.0.0.1:5984/puppet", "The url where the puppet couchdb database will be created"] + ) + setdefaults(:transaction, :tags => ["", "Tags to use to find resources. If this is set, then only resources tagged with the specified tags will be applied. diff --git a/lib/puppet/feature/base.rb b/lib/puppet/feature/base.rb index 8a21fd30f..0ca408ce4 100644 --- a/lib/puppet/feature/base.rb +++ b/lib/puppet/feature/base.rb @@ -45,3 +45,6 @@ end Puppet.features.add(:win32, :libs => ["sys/admin", "win32/process", "win32/dir"]) raise Puppet::Error "Cannot determine basic system flavour" unless Puppet.features.posix? or Puppet.features.win32? + +# We have CouchDB +Puppet.features.add(:couchdb, :libs => ["couchrest"]) diff --git a/lib/puppet/indirector/couch.rb b/lib/puppet/indirector/couch.rb new file mode 100644 index 000000000..b328f5cb7 --- /dev/null +++ b/lib/puppet/indirector/couch.rb @@ -0,0 +1,68 @@ +require 'couchrest' +class Puppet::Indirector::Couch < Puppet::Indirector::Terminus + + # The CouchRest database instance. One database instance per Puppet runtime + # should be sufficient. + # + def self.db + @db ||= CouchRest.database! Puppet[:couchdb_url] + end + + def db; self.class.db end + + def find(request) + attributes_of db.get(id_for(request)) + rescue RestClient::ResourceNotFound + Puppet.debug "No couchdb document with id: #{id_for(request)}" + return nil + end + + # Create or update the couchdb document with the request's data hash. + # + # RKH:TODO: Do not depend on error handling, check if the document exists + # first. (Does couchrest support this?) + # + def save(request) + raise ArgumentError, "PUT does not accept options" unless request.options.empty? + + # Try to find an existing document. + doc = db.get(id_for(request)) + doc.merge(hash_from(request)) + doc.save + rescue RestClient::ResourceNotFound + # Document does not yet exist, create it + db.save_doc hash_from(request) + end + + private + + # The attributes hash that is serialized to CouchDB as JSON. It includes + # metadata that is used to help aggregate data in couchdb. Add + # model-specific attributes in subclasses. + # + def hash_from(request) + { + "_id" => id_for(request), + "puppet_type" => document_type_for(request) + } + end + + # The couchdb response stripped of metadata, used to instantiate the model + # instance that is returned by save. + # + def attributes_of(response) + response.reject{|k,v| k =~ /^(_rev|puppet_)/ } + end + + def document_type_for(request) + request.indirection_name + end + + # The id used to store the object in couchdb. Implemented in subclasses. + # + def id_for(request) + raise NotImplementedError + end + +end + diff --git a/lib/puppet/indirector/facts/couch.rb b/lib/puppet/indirector/facts/couch.rb new file mode 100644 index 000000000..522fe3350 --- /dev/null +++ b/lib/puppet/indirector/facts/couch.rb @@ -0,0 +1,31 @@ +require 'puppet/node/facts' +require 'puppet/indirector/couch' +class Puppet::Node::Facts::Couch < Puppet::Indirector::Couch + + # Return the facts object or nil if there is no document + def find(request) + doc = super + doc ? model.new(doc['_id'], doc['facts']) : nil + end + + private + + # Facts values are stored to the document's 'facts' attribute. Hostname is + # stored to 'name' + # + def hash_from(request) + super.merge('facts' => request.instance.values) + end + + # Facts are stored to the 'node' document. + def document_type_for(request) + 'node' + end + + # The id used to store the object in couchdb. + def id_for(request) + request.key.to_s + end + +end + diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb index 2b086afea..0b9fc5879 100755 --- a/lib/puppet/node/facts.rb +++ b/lib/puppet/node/facts.rb @@ -49,6 +49,11 @@ class Puppet::Node::Facts end end + def ==(other) + return false unless self.name == other.name + strip_internal == other.send(:strip_internal) + end + private # Add internal data to the facts for storage. |