Class: PuppetDBQuery::MongoDB

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/puppetdb_query/mongodb.rb

Overview

access nodes and their facts from mongo database

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, #logger, #logger=

Constructor Details

#initialize(connection, nodes = :nodes, nodes_properties = :nodes_properties, meta = :meta) ⇒ MongoDB

initialize access to mongodb

You might want to adjust the logging level, for example:

::Mongo::Logger.logger.level = logger.level

Parameters:

  • connection

    mongodb connection, should already be switched to correct database

  • nodes (defaults to: :nodes)

    symbol for collection that contains nodes with their facts

  • nodes_properties (defaults to: :nodes_properties)

    symbol for collection for nodes with their update timestamps

  • meta (defaults to: :meta)

    symbol for collection with update metadata



23
24
25
26
27
28
# File 'lib/puppetdb_query/mongodb.rb', line 23

def initialize(connection, nodes = :nodes, nodes_properties = :nodes_properties, meta = :meta)
  @connection = connection
  @nodes_collection = nodes
  @nodes_propeties_collection = nodes_properties
  @meta_collection = meta
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



9
10
11
# File 'lib/puppetdb_query/mongodb.rb', line 9

def connection
  @connection
end

#meta_collectionObject (readonly)

Returns the value of attribute meta_collection.



12
13
14
# File 'lib/puppetdb_query/mongodb.rb', line 12

def meta_collection
  @meta_collection
end

#nodes_collectionObject (readonly)

Returns the value of attribute nodes_collection.



10
11
12
# File 'lib/puppetdb_query/mongodb.rb', line 10

def nodes_collection
  @nodes_collection
end

#nodes_properties_collectionObject (readonly)

Returns the value of attribute nodes_properties_collection.



11
12
13
# File 'lib/puppetdb_query/mongodb.rb', line 11

def nodes_properties_collection
  @nodes_properties_collection
end

Instance Method Details

#factsObject

get all nodes and their facts



63
64
65
66
67
68
69
70
71
# File 'lib/puppetdb_query/mongodb.rb', line 63

def facts
  collection = connection[nodes_collection]
  result = {}
  collection.find.batch_size(999).each do |values|
    id = values.delete('_id')
    result[id] = values
  end
  result
end

#meta_fact_update(method, ts_begin, ts_end) ⇒ Object

update or insert timestamps for given fact update method



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/puppetdb_query/mongodb.rb', line 114

def meta_fact_update(method, ts_begin, ts_end)
  connection[meta_collection].find_one_and_update(
    {},
    {
      '$set' => {
        last_fact_update: {
          ts_begin: ts_begin,
          ts_end:   ts_end,
          method:   method
        },
        method => {
          ts_begin: ts_begin,
          ts_end:   ts_end
        }
      }
    },
    { upsert: true }
  )
end

#node_delete(node) ⇒ Object

delete node data for given node name



87
88
89
# File 'lib/puppetdb_query/mongodb.rb', line 87

def node_delete(node)
  connection[nodes_collection].find(_id: node).delete_one
end

#node_facts(node) ⇒ Object

get facts for given node name



55
56
57
58
59
60
# File 'lib/puppetdb_query/mongodb.rb', line 55

def node_facts(node)
  collection = connection[nodes_collection]
  result = collection.find(_id: node).limit(999).batch_size(999).to_a.first
  result.delete("_id") if result
  result
end

#node_properties_update(new_node_properties, ts_begin) ⇒ Object

update node properties



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/puppetdb_query/mongodb.rb', line 92

def node_properties_update(new_node_properties, ts_begin)
  collection = connection[nodes_properties_collection]
  old_names = collection.find.batch_size(999).projection(_id: 1).map { |k| k[:_id] }
  delete = old_names - new_node_properties.keys
  collection.insert_many(nodes_properties.map { |k, v| v.dup.tap { v[:_id] = k } })
  collection.delete_many(_id: { '$in' => delete })
  ts_end = Time.iso8601(Time.now)
  connection[meta_collection].find_one_and_update(
    {},
    {
      '$set' => {
        last_node_properties_update: {
          ts_begin: ts_begin,
          ts_end:   ts_end
        }
      }
    },
    { upsert: true }
  )
end

#node_update(node, facts) ⇒ Object

update or insert facts for given node name



74
75
76
77
78
79
80
81
82
83
84
# File 'lib/puppetdb_query/mongodb.rb', line 74

def node_update(node, facts)
  connection[nodes_collection].find(_id: node).replace_one(facts, upsert: true)
rescue ::Mongo::Error::OperationFailure => e
  # mongodb doesn't support keys with a dot
  # see https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names
  # as a dirty workaround we delete the document and insert it ;-)
  # The dotted field .. in .. is not valid for storage. (57)
  raise e unless e.message =~ /The dotted field /
  connection[nodes_collection].find(_id: node).delete_one
  connection[nodes_collection].insert_one(facts.merge(_id: node))
end

#nodesObject

get all node names



49
50
51
52
# File 'lib/puppetdb_query/mongodb.rb', line 49

def nodes
  collection = connection[nodes_collection]
  collection.find.batch_size(999).projection(_id: 1).map { |k| k[:_id] }
end

#query_facts(query, facts) ⇒ Object

get nodes and their facts that fulfill given mongodb query



37
38
39
40
41
42
43
44
45
46
# File 'lib/puppetdb_query/mongodb.rb', line 37

def query_facts(query, facts)
  fields = Hash[facts.collect { |fact| [fact.to_sym, 1] }]
  collection = connection[nodes_collection]
  result = {}
  collection.find(query).batch_size(999).projection(fields).each do |values|
    id = values.delete('_id')
    result[id] = values
  end
  result
end

#query_nodes(query) ⇒ Object

get node names that fulfill given mongodb query



31
32
33
34
# File 'lib/puppetdb_query/mongodb.rb', line 31

def query_nodes(query)
  collection = connection[nodes_collection]
  collection.find(query).batch_size(999).projection(_id: 1).map { |k| k[:_id] }
end