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 rubocop:disable Metrics/ClassLength

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, #logger, #logger=

Constructor Details

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

initialize access to mongodb

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

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


25
26
27
28
29
30
# File 'lib/puppetdb_query/mongodb.rb', line 25

def initialize(connection, nodes = :nodes, node_properties = :node_properties, meta = :meta)
  @connection = connection
  @nodes_collection = nodes
  @node_properties_collection = node_properties
  @meta_collection = meta
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



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

def connection
  @connection
end

#meta_collectionObject (readonly)

Returns the value of attribute meta_collection.



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

def meta_collection
  @meta_collection
end

#node_properties_collectionObject (readonly)

Returns the value of attribute node_properties_collection.



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

def node_properties_collection
  @node_properties_collection
end

#node_properties_update_timestampObject (readonly)

Returns the value of attribute node_properties_update_timestamp.



14
15
16
# File 'lib/puppetdb_query/mongodb.rb', line 14

def node_properties_update_timestamp
  @node_properties_update_timestamp
end

#nodes_collectionObject (readonly)

Returns the value of attribute nodes_collection.



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

def nodes_collection
  @nodes_collection
end

Instance Method Details

#all_nodesObject

get all node names



44
45
46
47
# File 'lib/puppetdb_query/mongodb.rb', line 44

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

#facts(facts = []) ⇒ Object

get all nodes and their facts



132
133
134
135
136
137
138
139
140
141
# File 'lib/puppetdb_query/mongodb.rb', line 132

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

#metaObject

get meta informations about updates



144
145
146
147
148
149
# File 'lib/puppetdb_query/mongodb.rb', line 144

def meta
  collection = connection[meta_collection]
  result = collection.find.first
  result.delete(:_id)
  result
end

#meta_fact_update(method, ts_begin, ts_end) ⇒ Object

update or insert timestamps for given fact update method



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/puppetdb_query/mongodb.rb', line 194

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

#meta_node_properties_update(ts_begin, ts_end) ⇒ Object

update or insert timestamps for node_properties_update



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/puppetdb_query/mongodb.rb', line 215

def meta_node_properties_update(ts_begin, ts_end)
  connection[meta_collection].find_one_and_update(
    {},
    {
      '$set' => {
        last_node_properties_update: {
          ts_begin: ts_begin.iso8601,
          ts_end:   ts_end.iso8601
        }
      }
    },
    { upsert: true }
  )
  @node_properties_update_timestamp = ts_begin
end

#node_delete(node) ⇒ Object

delete node data for given node name



170
171
172
# File 'lib/puppetdb_query/mongodb.rb', line 170

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

#node_propertiesObject

get all nodes and their update dates



33
34
35
36
37
38
39
40
41
# File 'lib/puppetdb_query/mongodb.rb', line 33

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

#node_properties_update(new_node_properties) ⇒ Object

update node properties



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/puppetdb_query/mongodb.rb', line 175

def node_properties_update(new_node_properties)
  collection = connection[node_properties_collection]
  old_names = collection.find.batch_size(999).projection(_id: 1).map { |k| k[:_id] }
  delete = old_names - new_node_properties.keys
  data = new_node_properties.map do |k, v|
    {
      replace_one:
      {
        filter: { _id: k },
        replacement: v,
        upsert: true
      }
    }
  end
  collection.bulk_write(data)
  collection.delete_many(_id: { '$in' => delete })
end

#node_update(node, facts) ⇒ Object

update or insert facts for given node name



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/puppetdb_query/mongodb.rb', line 155

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

#query_facts(query, facts = []) ⇒ Object

get nodes and their facts that fulfill given mongodb query



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

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_facts_exists(query, facts = []) ⇒ Object

get nodes and their facts that fulfill given mongodb query and have at least one value for one the given fact names



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

def query_facts_exists(query, facts = [])
  result = query_facts(query, facts)
  unless fact_names.empty?
    result.keep_if do |_k, v|
      fact_names.any? { |f| !v[f].nil? }
    end
  end
  result
end

#query_nodes(query) ⇒ Object

get node names that fulfill given mongodb query



52
53
54
55
# File 'lib/puppetdb_query/mongodb.rb', line 52

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

#search_facts(query, pattern, facts = [], facts_found = [], check_names = false) ⇒ Object

get nodes and their facts for a pattern



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

def search_facts(query, pattern, facts = [], facts_found = [], check_names = false)
  collection = connection[nodes_collection]
  result = {}
  collection.find(query).batch_size(999).each do |values|
    id = values.delete('_id')
    found = {}
    values.each do |k, v|
      if v =~ pattern
        found[k] = v
      elsif check_names && k =~ pattern
        found[k] = v
      end
    end
    facts_found.concat(found.keys).uniq!
    next if found.empty?
    facts.each do |f|
      found[f] = values[f]
    end
    result[id] = found
  end
  result
end

#single_node_facts(node, facts) ⇒ Object

get facts for given node name



121
122
123
124
125
126
127
# File 'lib/puppetdb_query/mongodb.rb', line 121

def single_node_facts(node, facts)
  fields = Hash[facts.collect { |fact| [fact.to_sym, 1] }]
  collection = connection[nodes_collection]
  result = collection.find(_id: node).limit(1).batch_size(1).projection(fields).to_a.first
  result.delete("_id") if result
  result
end