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

Parameters:

  • connection

    mongodb connection, should already be switched to correct database

  • nodes (defaults to: :nodes)

    symbol for collection that contains nodes with their facts

  • node_properties (defaults to: :node_properties)

    symbol for collection for nodes with their update timestamps

  • meta (defaults to: :meta)

    symbol for collection with update metadata



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

Parameters:

  • facts (Array<String>) (defaults to: [])

    get these facts in the result, eg [‘fqdn’], empty for all



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

Parameters:

  • node (String)

    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

Parameters:

  • node (String)

    node name

  • facts (Array<String>)

    get these facts in the result, eg [‘fqdn’], empty for all



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

Parameters:

  • query

    mongodb query

  • facts (Array<String>) (defaults to: [])

    get these facts in the result, eg [‘fqdn’], empty for all



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

Parameters:

  • query

    mongodb query

  • facts (Array<String>) (defaults to: [])

    get these facts in the result, eg [‘fqdn’], empty for all



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

Parameters:

  • query

    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

Parameters:

  • query

    mongodb query

  • pattern (RegExp)

    search for

  • facts (Array<String>) (defaults to: [])

    get these facts in the result, eg [‘fqdn’], empty for all

  • facts_found (Array<String>) (defaults to: [])

    fact names are added to this array

  • check_names (Boolean) (defaults to: false)

    also search fact names



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

Parameters:

  • node (String)

    node name

  • facts (Array<String>)

    get these facts in the result, eg [‘fqdn’], empty for all



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