class DataMapper::Adapters::PuppetdbAdapter
Attributes
host[RW]
http[RW]
port[RW]
ssl[RW]
Public Class Methods
new(name, options = {})
click to toggle source
Calls superclass method
# File lib/dm-puppetdb-adapter/adapter.rb, line 21 def initialize(name, options = {}) super Puppet.initialize_settings unless Puppet[:confdir] # Set some defaults @host = @options[:host] || 'puppetdb' @port = @options[:port] || 443 @ssl = @options[:ssl] || true @http = Puppet::Network::HttpPool.http_instance(@host, @port, @ssl) end
Public Instance Methods
read(query)
click to toggle source
# File lib/dm-puppetdb-adapter/adapter.rb, line 13 def read(query) model = query.model query.filter_records(puppetdb_get(model.storage_name(model.repository_name), build_query(query))) end
Private Instance Methods
build_query(query)
click to toggle source
contruct a puppetdb query from a datamapper query
# File lib/dm-puppetdb-adapter/adapter.rb, line 35 def build_query(query) conditions = query.conditions if conditions.nil? nil else puppetdb_condition(conditions, query.model) end end
format_value(value)
click to toggle source
format a value in a query especially make sure timestamps have correct format
# File lib/dm-puppetdb-adapter/adapter.rb, line 104 def format_value(value) if value.is_a? Date or value.is_a? Time value.strftime('%FT%T.%LZ') else value end end
puppetdb_condition(c, model)
click to toggle source
return puppetdb syntax for a condition
# File lib/dm-puppetdb-adapter/adapter.rb, line 46 def puppetdb_condition(c, model) case c when DataMapper::Query::Conditions::NullOperation nil when DataMapper::Query::Conditions::AbstractOperation q = [c.class.slug.to_s, *c.operands.map { |o| puppetdb_condition o, model }.compact] # In case we couldn't build any query from the contained # conditions return nil instead of a empty and return q.last if q.count == 2 return nil if q.count < 2 return q end # Determine the property we should match on if c.subject.kind_of? DataMapper::Property property = c.subject elsif c.subject.kind_of? DataMapper::Associations::Relationship property = c.subject.parent_key.first else puts "Unhandled subject #{c.subject.inspect}" raise RuntimeError, "Unhandled subject #{c.subject.inspect}" end # We can only do comparison on certain fields # on the server side if property.model.respond_to? :server_fields return nil unless property.model.server_fields.include? property.name end case c when DataMapper::Query::Conditions::EqualToComparison ['=', property.field, format_value(c.value)] when DataMapper::Query::Conditions::RegexpComparison ['~', property.field, format_value(c.value)] when DataMapper::Query::Conditions::LessThanComparison ['<', property.field, format_value(c.value)] when DataMapper::Query::Conditions::GreaterThanComparison ['>', property.field, format_value(c.value)] # The following comparison operators aren't supported by PuppetDB # So we emulate them when DataMapper::Query::Conditions::LikeComparison ['~', property.field, c.value.gsub('%', '.*')] when DataMapper::Query::Conditions::LessThanOrEqualToComparison ['or', ['=', property.field, format_value(c.value)], ['<', property.field, format_value(c.value)]] when DataMapper::Query::Conditions::GreaterThanOrEqualToComparison ['or', ['=', property.field, format_value(c.value)], ['>', property.field, format_value(c.value)]] when DataMapper::Query::Conditions::InclusionComparison if c.value.kind_of? Range ['or', ['=', property.field, format_value(c.value.first)], ['>', property.field, format_value(c.value.first)], ['<', property.field, format_value(c.value.last)], ['=', property.field, format_value(c.value.last)]] else ['or', *c.value.collect { |v| ['=', property.field, v.value]} ] end end end
puppetdb_get(path, query=nil)
click to toggle source
# File lib/dm-puppetdb-adapter/adapter.rb, line 112 def puppetdb_get(path, query=nil) uri = "/#{path}?query=" uri += URI.escape query.to_json.to_s unless query.nil? resp = @http.get(uri, { "Accept" => "application/json" }) raise RuntimeError, "PuppetDB query error: [#{resp.code}] #{resp.msg}, endpoint: #{path}, query: #{query.to_json}" unless resp.kind_of?(Net::HTTPSuccess) # Do a ugly hack because Hash and Array # properties aren't supported so we preserve them as JSON JSON.parse(resp.body).collect do |i| i.each do |k,v| i[k] = v.to_json if v.is_a? Hash or v.is_a? Array end end end